Yüke kaynak kimliği eklemek veya URI'den türetmek için


13

Bir API tasarlarken, bir PUT yükünün güncellenen kaynağın kimliğini içermesi gerekip gerekmediği sorusuyla karşılaştık.

Şu anda sahip olduğumuz şey:

PUT /users/123 Payload: {name: "Adrian"}

Rota kodumuz kimliği URI'den çıkarır ve güncellemeye devam eder.

API'mızın ilk kullanıcıları, neden yükte kimliğe izin vermediğimizi sorguluyor:

PUT /users/123 Payload: {id: 123, name: "Adrian"}

Buna izin vermememizin nedeni, yükün ve URI'nin kimliğinin çoğaltılmış olmasıdır.

Bunu biraz daha düşünerek, kaynağı URI ile birleştiriyoruz.

URI'nin kimliği yoksa, yükün değiştirilmesi gerekir:

PUT /no/id/here Payload: {name: "Adrian"} < What user???

Yapmamak için herhangi bir neden var mı?

Yanıtlar:


14

Sen edilir sözde Üniforma çifte Kaynak için Tanıtıcı kaynak .

HTTP ile REST uygulandığında, kaynağın geçerli değerini almak için GET ve yeni bir değer ayarlamak için PUT kullanırsınız. GET'in bir yükü yoktur, bu nedenle kaynağın URI tarafından tanımlanması gerekir. Ve PUT mantıksal olarak aynı URI'ye yapılır ve yük, bir sonraki GET'in geri dönmesini istediğiniz gibi görünmelidir.

POST'u farklı URI için kullanabilirsiniz, ancak GET'e gereksiz yere asimetrik olacağı için daha az mantıklı olacaktır. Ortak URI'ye POST yalnızca yeni kaynaklar oluşturmak için mantıklı olabilir ( POST /users/new, faydalı yük:, {name: "Adrian"}yanıt {id: 345, name: "Adrian"}), ancak bu idempotent değildir ve bu nedenle kaçınılmalıdır REST için uğraşıyorsanız¹. Bunun yerine kimliği bir çağrı ile ayırmalı ve sonra yeni kimliği ayarlamak için PUT'u kullanmalısınız; Bu, hataya dayanıklıdır, çünkü ilk istek başarısız olursa, kimlik rezervasyonu zaman aşımına uğrayabilir ve PUTidempotenttir. Veya istemci tarafından oluşturulan UUID'yi kullanın.


EST REST'in tanımı idempotence hakkında bir şey söylemez, bu yüzden idempotent olmayan işlemleriniz varsa REST olmadığını iddia edemem. Bu, idempotent isteklere bağlı kalmanın, işleri karmaşıklaştırmadan daha güvenilir hale getirdiği ve bu nedenle tavsiye edildiği gerçeğini değiştirmez.


3
Bildiğim kadarıyla bir POST isteği idempotent olmak zorunda değildir. Bu nedenle, yayınlamada herhangi bir sorun görmüyorum /users('yeni' eklemeye gerek yok).
lex82

cevabın için teşekkürler. Tüm isteklerde idempotency olması güzel bir özellik olduğunu görüyorum, ancak kim bunun bir REST API için gerekli olduğunu söylüyor? Kendilerini RESTful olarak adlandıran kesinlikle birçok API, idempotent olmayan POST isteklerine izin verir (özellikle sunucu yeni kaynaklar için kimlikler oluşturduğunda). Ancak REST'in çok katı bir tanımını uygulasanız bile, yukarıdaki örnekte olduğu gibi, idempotent olmayan POST'larla hangi mimari kısıtlamanın ihlal edildiğini görmüyorum.
lex82

Bir kısıtlamayı ihlal eden POST isteklerini kesinlikle görüntüleyebilirim. Neden bir koleksiyona kaynak göndermek ve sunucunun kimliğine karar vermesine izin vermek REST kısıtlamalarının ihlali olduğunu anlamıyorum.
lex82


3
POST'un tüm fikri
cesaret kırıcı

2

Bunu biraz daha düşünerek, kaynağı URI ile birleştiriyoruz.

URI'nin kimliği yoksa, yükün değiştirilmesi gerekir:

PUT / no / id / here Yük: {ad: "Adrian"} <Hangi kullanıcı ???

Yapmamak için herhangi bir neden var mı?

Bu sorunun cevabı, istemcinin kimliği değiştirmesine izin vermek isteyip istemediğinize bağlıdır?

İstemci kimliği bir PUT aracılığıyla değiştirebilirse, kaynağın URI'si değişecektir ve bir kaynak eski URI'ye her eriştiğinde 301 Kalıcı Olarak Taşınmalıdır.

Örneğin,

/users/123

ve istemci aşağıdakileri kaynağa koyar

{id: 222, name: "Adrian"}

kaynak güncellendi ve URI'si şimdi

/users/222

LocationEğer giderseniz PUT cevaben alan yeni URI içerir ve gereken /users/123bir almalısınız sizin 301Yer alan yeni işaret ile tepkisini /users/222kaynak.

Çoğu durumda, istemcinin kimliği değiştirmesini istemiyor olsanız da, bu oldukça hızlı bir şekilde dağınık hale gelebilir. Bu durumda kimlik, yalnızca sunucunun değiştirebileceği bir şeydir ve istemci bu durumu güncelleyemediği için PUT gövdesinin dışında bırakmalısınız.

Aynı kaynakta farklı bir URI için bir gereksinim koyarsanız,

/users/adian_lync

bu kaynak mevcut değilse, sunucu kaynağı oluşturmalı ve bunu yaparken oluşturmalı ve tanımlamalıdır


1
Kimliğin yüke yerleştirilmesini sorgulamamızın nedeni, Backbone.js'nin kimliği varsayılan olarak bir PUT isteğinde geçirmesinden kaynaklanıyordu. Bunun olmasını engelleyebiliriz, ama şimdi bunun varsayılan davranış neden olduğunu bilmek istiyorum.
Adrian Lynch

1
Korkarım Backbone.js'ye aşina değilim. Kimlik URL'ye de dahil edilmişse gereksiz görünmektedir. Belki de geliştiriciler tarafından bir gözetim
Cormac Mulhall
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.