kabul edilebilir yan etkileri olan bir PUT kullanıyor (REST)


9

Kullanıcı bir formu güncellediğinde geri alma geçmişi oluşturmak istiyorum. Bu bir güncelleme olduğundan, bir PUT isteği kullanmak istiyorum. Ancak, PUT'un hiçbir yan etkisi olmaması gerektiğini okudum .

Burada PUT kullanmak kabul edilebilir mi? Daha iyi alternatifler var mı?

PUT /person/F02E395A235

{
   time: 1234567,
   fields: {
      name: 'John',
      age: '41'
   }
}

Sunucuda

doPut('person/:personId',
   // create a new person snapshot
)

Düzenle:

Geçmiş kullanıcı tarafından görülebilir, birden çok kez çağırmak birden çok sürümle sonuçlanır.

Çözüm, sürümü oluşturmadan önce benzersiz olup olmadığını kontrol etmekti.

Yanıtlar:


11

HTTP / 2 hazırlayan insanlar, HTTP'nin ne yapması gerektiğine dair fikirleri hakkında çok daha ayrıntılıydı ve eski anlamı korudu. HTTP / 2 taslak spesifikasyonunun idempotence hakkında ne söylediğini görelim:

4.2.2. İdempotent Yöntemler

Bu yöntemle birden çok özdeş isteğin sunucu üzerindeki amaçlanan etkisi, bu tür bir isteğin etkisiyle aynı ise, bir istek yöntemi "idempotent" olarak kabul edilir. yöntemler idempotenttir.

Safe tanımı gibi, idempotent özelliği de yalnızca kullanıcı tarafından talep edilenler için geçerlidir; bir sunucu her isteği ayrı ayrı günlüğe kaydedebilir, bir düzeltme denetim geçmişini saklayabilir veya her idempotent istek için diğer idempotent olmayan yan etkileri uygulayabilir .

Bu tür bir PUT isteği için sunucu üzerindeki amaçlanan etki, söz konusu URI tarafından tanımlanan kaynağı güncellemektir . Sizin durumunuzda olan da budur.

Sürüm kaynaklarına karar vermenin burada bir önemi yok. Hiçbir şey değişmediğinde yeni bir sürüm oluşturmak istemiyorsanız, PUT isteğindeki yükü kaynağın en son (veya başka bir şekilde tanımlanmış) sürümüyle ve özelliklerin hiçbiri değişmediğinde karşılaştırmanız gerekir yeni bir sürüm oluşturmamayı seçebilirsiniz .


Düzenlemeniz:

Geçmiş kullanıcı tarafından görülebilir, birden çok kez çağrı yapmak birden fazla sürüme neden olur

Kaynak söz konusu olduğunda, bunun bir yan etkisi yoktur . Bu URI'deki kaynak değişmez (aynı özellikler PUT alır). Büyük olasılıkla farklı bir URI veya farklı istek üstbilgileri tarafından istendiği için geçmiş yalnızca meta verilerdir.



Hangi soruna bir çözüm bu? Yani timemülkiyet güncellenir? Size öyle olsa bile çok meta olduğunu düşünüyorum içinde kaynak.
CodeCaster

1
Sorun, birden çok PUT gönderildiğinde, kullanıcının gereksiz bilgiler içeren uzun bir geri alma geçmişi almasıydı. benzersizliği kontrol etmek bunu çözer
roo2

12

HTTP iki özelliği birbirinden ayırır:

  • Idempotency
  • Emniyet

İdempotency spec tarafından aşağıdaki gibi tanımlanır:

Metodlar ayrıca " idempotence " özelliğine de sahip olabilirler (bu, hata veya son kullanma sorunlarının yanı sıra) N> 0 özdeş isteklerin yan etkilerinin tek bir istekle aynı olmasıdır. Yöntemleri GET, HEAD, PUTve DELETEbu özelliği paylaşır. Ayrıca, yöntemler OPTIONSve yan etkileri TRACE OLMAMALIDIR ve bu nedenle doğası gereği idempotenttir.

Ve Güvenlik:

Özellikle, sözleşmenin GETve HEADyöntemlerinin geri alma dışında bir işlem yapmanın önemi OLMAMASI gerektiği belirlenmiştir. Bu yöntemler " güvenli " olarak kabul edilmelidir . Bu kullanıcı ajanları gibi başka yöntemler, temsil edilmesini sağlar POST, PUTve DELETEkullanıcı bir olasılıkla güvensiz bir eylem talep ediliyor farkında yapılır böylece, özel bir şekilde,.

Doğal olarak, bir GETisteğin gerçekleştirilmesi sonucunda sunucunun yan etkiler yaratmamasını sağlamak mümkün değildir ; Aslında, bazı dinamik kaynaklar bir özellik olduğunu düşünüyor. Buradaki önemli ayrım, kullanıcının yan etkileri talep etmemesidir, bu nedenle kendilerinden sorumlu tutulamaz.

Güvenliğin idempotency anlamına geldiğine dikkat edin: eğer bir yöntemin yan etkisi yoksa, birden çok kez gerçekleştirilmesi, bir kez gerçekleştirilmesi ile aynı yan etkiyi, yani hiçbirini vermez.

Bu, yöntemleri üç kategoriye ayırır:

  • Kasa (bu nedenle de ve İdempotent) GET, HEAD, OPTION,TRACE
  • İdempotent ancak mutlaka güvenli değildir: PUT,DELETE
  • ne idempotent ne de güvenli: POST

PUT'un hiçbir yan etkisi olmamalıdır.

Bu yanlış. PUTidempotent ama güvenli değil. Bütün noktası arasında PUT, yani bir kaynak güncelleme, bir yan etkiye sahip olmaktır. İdempotency, aynı kaynağı aynı içeriklerle birden çok kez güncellemenin, yalnızca bir kez güncellemekle aynı etkiye sahip olması gerektiği anlamına gelir.

Güvenlik ile ilgili bölümdeki son paragrafa dikkat edin:

Doğal olarak, bir GETisteğin gerçekleştirilmesi sonucunda sunucunun yan etkiler yaratmamasını sağlamak mümkün değildir ; Aslında, bazı dinamik kaynaklar bir özellik olduğunu düşünüyor. Buradaki önemli ayrım, kullanıcının yan etkileri talep etmemesidir, bu nedenle kendilerinden sorumlu tutulamaz .

Bu cümle hakkında konuşmaktan GETve güvenlikten bahsetmekle birlikte, yazarların da aynı mantığı PUTve beceriksizliği uygulamak istediklerini varsayabiliriz . IOW: adlandırılmış kaynağı güncelleyen, PUTyalnızca bir kullanıcı tarafından görülebilir yan etkiye sahip olmalıdır . Bu olabilir diğer yan etkilere sahip, ancak kullanıcı onlardan sorumlu tutulamaz.

Örneğin PUT, idempotent olduğu gerçeği, istediğim kadar tekrar deneyebileceğim anlamına gelir: spec , birden çok kez çalıştırmanın, bir kez yürütmekle tamamen aynı olacağını garanti eder. Bu çoklu PUTisteklerin bir yan etkisi olarak eski revizyonlar biriktirme listesi oluşturmak tamamen geçerlidir . Ancak, birden çok yeniden deneme sonucunda veritabanınız eski revizyonlardan oluşan bir birikim ile dolarsa, bu benim sorunum değil, bu sizin.

IOW: İstediğiniz kadar yan etkiye sahip olmanıza izin verilir, ancak

  1. kullanıcıya istekleri idempotent gibi görünmelidir
  2. bu yan etkilerden siz sorumlusunuz, kullanıcı değil

Evet, idempotency, PUT'un eyleminden etkilenen diğer sunucu / hizmet durumlarıyla değil, konulan kaynağın durumuyla ilgilidir.
Marjan Venema

Rest
roo2'de

Harika bir açıklama. Ancak, bunun gibi birkaç ifade yaparsınız: "PUT'un tüm amacı bir yan etki, yani bir kaynağı güncellemektir." "Yan etki" terimi ile "birincil, amaçlanan etkiye ek olarak ortaya çıkan ikincil veya kasıtsız bir şeyden" farklı bir şey ifade etmedikçe bu bir çelişki gibi görünür.
MarredCheese

@MarredCheese: Terimi standart programlama anlamında kullanıyorum, bu da temel olarak "dönüş değeri olmayan herhangi bir" sonuç "anlamına geliyor.
Jörg W Mittag

Ah, elbette. Açıklama için teşekkürler.
MarredCheese

1

PUT hiçbir yan etkisi olması gerektiği doğru , ancak ben buna bir şey eklemek istiyorum.

PUT'un, PUT işleminin gerçekleştirildiği kaynak üzerinde herhangi bir yan etkisi olması gerekmez

Olarak persontanımlanan bir kaynağı güncelleştiriyorsunuz F02E395A235, bu nedenle PUT kullanımı doğru. Artık bir iş kuralı olarak, arayan varlık (REST hizmetinin tüketicisi) tarafından görülmeyen değişiklikleri de takip edersiniz. Bu, personkaynağa yeni bir öğe eklemez . Geçmiş anlık görüntüye /person/bitiş noktası kullanılarak erişilemez . Bu yüzden PUT'un bu durumda mükemmel kabul edilebilir olması gerektiğine inanıyorum.


1
Alınan kaynak üzerinde hiçbir yan etki yoktur, ancak diğer şeyler üzerindeki herhangi bir sayıda yan etki (sayaçlar, günlük kaydı, denetim izleri, ...) mükemmel bir şekilde kabul edilebilir.
Marjan Venema
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.