RESTful hizmetinde CRUD dışı işlemler


106

Bir RESTful hizmetine CRUD dışı işlemleri eklemenin "RESTful" yolu nedir? Aşağıdaki gibi kayıtlara CRUD erişimine izin veren bir hizmetim olduğunu varsayalım:

GET /api/car/123           <- Returns information for the Car object with ID 123
POST /api/car              <- Creates a new car (with properties in the request)
PUT /api/car/123           <- Updates car 123 (with properties in the request)
DELETE /api/car/123        <- Deletes car 123    
POST /api/car/123/wheel/   <- Creates a wheel and associates it to car 123

Arabanın rengini değiştirmek istersem, basitçe POST /api/car/123ve yeni renk için bir POST değişkeni eklerim.

Ancak bir araba satın almak istediğimi varsayalım ve bu işlem bir "kullanıcı" kaydının "sahip olunan araba" özelliğini güncellemekten daha karmaşıktır. POST /api/car/123/purchase"Satın alma" nın aslında bir yöntem adı olduğu gibi basitçe bir şey yapmak DİNLENMELİ midir? Veya PURCHASEyerine özel bir HTTP fiili POSTmi kullanmalıyım ?

Veya CRUD dışı operasyonlar tamamen REST kapsamı dışında mı?


5
Bir arabanın rengini değiştiriyorsanız, PATCH /api/car/123bir renk parametresi kullanmak PUT /api/car/123ve göndermek VEYA tüm araba nesnesini kullanmak ve göndermek daha iyi olacaktır . POST, yeni bir araba yarattığınız sonucuna
varabilir

Yanıtlar:


65

RESTful sözlüğünde bir işletme veya kaynak olarak satın almayı düşünün . Bununla birlikte, bir satın alma yapmak aslında yeni bir kaynak yaratmaktır. Yani:

POST /api/purchase

yeni bir sipariş verecek. Bu adrese gönderilen içeriğin içindeki ayrıntılara (kullanıcı, araba, vb.) Kimlik (veya URI) ile başvurulmalıdır.

Bir araba sipariş etmenin sadece veri tabanında basit bir EKLEME olmadığı önemli değil. Aslında, REST veritabanı tablolarınızı CRUD işlemleri olarak göstermekle ilgili değildir. Mantıksal açıdan bir sipariş oluşturuyorsunuz (satın alma), ancak sunucu tarafı istediği kadar işlem adımı yapmakta özgür.

Hatta HTTP protokolünü daha da kötüye kullanabilirsiniz. LocationYeni oluşturulan siparişe bir bağlantı döndürmek için üstbilgiyi kullanın , kullanıcıları sorunlar (sunucu veya istemci tarafı) vb. Hakkında bilgilendirmek için HTTP yanıt kodlarını dikkatlice seçin.


3
REST tamamen kaynakların durumunu manipüle etmekle ilgilidir ve her iş operasyonunun CRUD operasyonlarının durumuna göre eşleştirilmesi gerekir. Zor iş operasyonları semantiğine ihtiyacınız varsa , SOAP yoluna gitmeniz gerekir (SOAP aslında mesaj geçirmedir, ancak tipik olarak istek-yanıt işlemlerinde düzenlenir).
Tomasz Nurkiewicz

23
"Kaynak olarak satın alma" tasarımı düzgün görünüyor. Ya kaynak bir "bira" ise .. ve sunucunun onu içmesini istersem .. (benim içindi, kesinlikle ALIRIM;)) .. "içki eylemini" bir kaynak olarak düşünmeli miyiz ?! .. veya "bira içmek" zor bir iş operasyonu mu? Daha ciddisi, eylemleri kaynak olarak düşünmekle ilgili RESTful tasarım mı
?!

2
Bir REST hizmeti aracılığıyla "satın alma siparişini onaylama" yı nasıl ifşa edersiniz? Bence @TomaszNurkiewicz, CRUD yoluyla düzgün bir şekilde yapılamayan her şeyin SOAP tarafından sağlanan operasyon-semantiğe ihtiyaç duyacağı konusunda haklı. "Satın alma siparişi onayı" kendi başına bir model / varlık olmadığı sürece. Örneğin POST / po-onayı (istekte PO ayrıntıları ile).
mydoghasworms

2
Bir REST müşterisinin bakış açısından "satın alma siparişini onayla", siparişin yalnızca başka bir güncellemesi olmalıdır. Örneğin, "Onaylandı" yı "doğru" olarak değiştirin ve güncellemeyi sunucuya gönderin. Sunucunun muhtemelen bir dizi kontrol yapması gerekecek ve muhtemelen bir sürü başka kaynağı güncellemesi / oluşturması gerekecek. Ancak bu sunucu sorunudur ve müşteri tarafından görülmemelidir.
AVee

2
@antinome: "Müşterinin bunun bir kısmını bildiğini varsayalım", eğer durum buysa, REST yapmıyorsanız (yine de geçerli, mantıklı bir yazılım olabilir!). REST, bu tür bir şeyi bilmeyen istemciler oluşturabilmek, sunucunun davranışı değiştiğinde hala çalışan istemciler oluşturmak üzere tasarlanmıştır. Yapmaya çalıştığınız şey klasik RPC, ya yaklaşımınızı REST'e uyacak şekilde gözden geçirmeniz ya da RPC yaptığınızı ve SOAP gibi RPC için tasarlanmış bir protokol kullandığınızı kabul etmeniz gerekir. REST, RPC olmamak için çok uğraşıyor, bu nedenle RPC istediğinizde / ihtiyacınız olduğunda asla iyi bir uyum olmayacak.
AVee

15

Anladığım kadarıyla RESTful yolu, yeni HTTP fiillerine ihtiyacınız olmaması, bir yerde yapmanız gerekenleri ifade edecek bir isim var.

Araba mı satın alacaksınız? Değil mi

POST /api/order

2
PUT idempotent olduğu için kaynakları güncellemek için kullanılmıyor mu? Bu, onu istediğiniz kadar arayabileceğiniz anlamına gelir, ancak yalnızca ilk / son arama önemlidir. Öte yandan POST, kaynakları oluşturmak için kullanılır ve bunu iki kez çağırmak aslında iki tane oluşturmalıdır.
Tomasz Nurkiewicz

1
@Tomas, evet, yazım hatası. İlke önemli olsa da, yeni bir şeyle uğraşıyoruz, bir düzen, yeni bir fiile gerek yok.
djna

5

Gerçekten yaptığınız şey bir düzen yaratmaktır. Bu nedenle, sipariş ve gönderi için başka bir kaynak ekleyin ve sipariş işlemi sırasında oraya koyun.

Yöntem çağrıları yerine kaynaklar açısından düşünün.

Siparişi sonlandırmak için muhtemelen POST / api / order // tamamlamanız veya benzer bir şey yapmanız gerekir.


3

REST API'lerinin anlambilim sağlamaktan çok daha fazla şekilde yardımcı olduğunu düşünüyorum. Dolayısıyla, RPC çalışma tarzında daha anlamlı görünen bazı çağrılar nedeniyle RPC stilini seçemezsiniz. Örnek, iki yer arasındaki yönleri bulmaya yönelik google maps api'dir. Şuna benziyor: http://maps.googleapis.com/maps/api/directions/json?origin=Jakkur&destination=Hebbal

Buna "findDirections" (fiil) adını verebilir ve onu bir işlem olarak değerlendirebilirlerdi. Daha ziyade, bir kaynak olarak "yön" (isim) yaptılar ve yön bulmayı yönler kaynağında bir sorgu olarak ele aldılar (İçeride yön denen gerçek bir kaynak olmasa da ve parametrelere dayalı yönleri bulmak için iş mantığı tarafından uygulanabilir).


Bu kötü bir örnek. Bu durumda yönler (tüm olası yönler, sonsuz sayıda) kaynaktır ve parametreler sadece filtrelerdir. Ancak bununla bir "satın alma" yapamazsınız, çünkü filtreler yalnızca alma işlemleri ve bir sipariş verme veya iptal işlemi verileri değiştiren işlemlerdir
Tseng

2
satın alma, siparişin oluşturulduğunu belirtmek için gövdede bir json ile POST / sipariş olacaktır. iptal, bunun idempotent bir güncelleme olduğunu belirtmek için sipariş durumu değişikliğini taşıyan bir json ile PUT to / order olacaktır. Hala bir kaynak biçiminde ifade edilemeyen bir işlemle karşılaşacağım. Böyle bir örnek görmek isterim
Maruthi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.