Neden PATCH yöntemi belirsiz değil?


48

Bunu merak ediyordum.

Diyelim ki ve userile bir kaynak var . Bir alanı güncellemek istersem, bunun gibi bir kaynağa PATCH isteği yapabilirimidname

PATCH /users/42
{"name": "john doe"} 

Ve sonra uygulama kullanıcı 42 adını güncelleyecektir.

Peki neden bu talebi tekrarlarsam sonuç farklı olur?

RFC 5789’a göre

PATCH ne güvenli ne de iddiasız


ne zaman bir başkası arasında bir başkası kullanıcıyı 42 güncelleme isteği yaparsa{"name": "bendjamin franklin"}
gnat

@gnat da benzer bir argüman olarak kabul edilemez PUT yöntemi için geçerli değil mi? (bakınız goo.gl/t24ZSJ )
mattecapu

"PUT İdempotent semantiğini vardır ve (biz sunucuya kaynak eyaletinin tamamını göndermek yani) bu nedenle güvenle mutlak güncellemeler için kullanılabilir, ancak değil aynı zamanda göreli güncellemeler için (yani biz sadece kaynak durumuna değişir gönderme) , çünkü bu ihlal edecek anlambilimi ... "( POST ve PUT talep ediyor - sadece kongre mi? )
gnat

1
Açıkçası ... Fakat PUT'un önemsiz olmadığını söyleyebilirsiniz, çünkü iki eşit talep arasında ikinci bir müşteri iki arasında üçüncü bir talepte bulunabilir. Aynı argüman PATCH istekleri için de geçerlidir.
mattecapu

2
Bu soru bağlamında oldukça alakalı olduğuna inandığım için ilgili şartnameye bir referans ekleme özgürlüğünü aldım.
Pete

Yanıtlar:


34

Bir PATCH isteği önemsiz olabilir , ancak olması gerekmiyor. Önemsiz olarak nitelenmesinin nedeni budur.

PATCH'in önemsiz olup olmadığı, gerekli değişikliklerin nasıl iletildiğine büyük ölçüde bağlıdır.
Örneğin, yama formatı biçimindeyse, {change: 'Name' from: 'benjamin franklin' to: 'john doe'}ilkinden sonraki PATCH isteğinin ilk istekten farklı bir etkisi (bir başarısızlık yanıtı) olur.
Devamsızlığın diğer bir nedeni, değişikliği orijinal kaynağın dışındaki bir şeye uygulamak, kaynağı geçersiz kılabilir. Değişikliği birkaç kez uygularsanız, bu durum da geçerli olacaktır.


3
Son paragrafı anlamıyorum, "değişikliğin orijinal kaynaktan başka bir şeye uygulanmasının kaynağı geçersiz kılabileceğine" bir örnek verebilir misiniz ve bunun aynı kaynağa defalarca değişiklik yapmakla nasıl bir ilgisi var?
Robin Green,

3
@RobinGreen: Kaynağın XML'de en fazla bir <name>öğe olması şartıyla temsil edildiğini varsayalım . PATCH <name>bir kaynağa başlangıçta bir tane içermeyen bir öğe eklerse , PATCH'yi iki kez uygulamak (veya onu zaten a içeren bir kaynağa uygulamak <name>) kaynağı geçersiz kılar, çünkü birdenbire <name>izin verilmeyen iki öğe içerir bu tür kaynaklar için.
Bart van Ingen Schenau

13
Verdiğiniz ilk örnek, IMHO ile ilgili olduğu gibi, geçerli değil. Önemsiz olan DELETE örneği, ilk istek: kaynak var ancak silindi (2xx döndürür), ikinci istek: kaynak mevcut değil ve istekden sonra hala yok, 4xx döndürüyor. Sunucu durumu değişmedi, bu nedenle boşa gitti. Örneğinizde, ilk istek: BenFra'dan JohDoe'ya PATCH, kaynak adı BenFra idi, ama şimdi JohDoe (2xx döndürüyor), ikinci istek: BenFra'dan JohDoe'ya PATCH, kaynak adı JohDoe ve hala JohDoe (4xx döndürüyor). Yani bu PATCH'in düşüncesiz olamayacağını göstermiyor.
sp00m

Daha fazla ayrıntı burada: stackoverflow.com/q/4088350/1225328
sp00m

8

Bence iddiasız olmayan PATCH, RFC 5789'un bu paragrafı olduğunda açık cevap bence:

Ayrıca yama biçimlerinin bilinen bir temel noktadan (örneğin, metin dosyalarına günlük dosyalarına ekleme ya da çarpışmayan satırları veritabanı tablolarına ekleme) çalışması gerekmeyen durumlar da vardır, bu durumda müşteri taleplerinde aynı özen gerekli değildir .

RFC, yamanın kaynakta bazı "genel değişiklikler" içerdiğini belirttiğinden, sadece normal alan değişiminin ötesine bakmalıyız. Eğer kaynak bir sayaç için ise, o zaman yama, açıkça idempotet olmayan bir artış talep edebilir.


2

PATCHistekler, bir kaynağa uygulanacak işlemler kümesini tanımlar; aynı işlemi aynı kaynağa iki kez uygularsanız, sonuç aynı olmayabilir. Bunun nedeni operasyonları tanımlamanın size kalmış olmasıdır. Diğer bir deyişle, birleştirme kurallarını tanımlamanız gerekir .

PATCHKaynakları yalnızca JSON'a değil, birçok farklı formatta yamalamak için kullanılabileceğini unutmayın .

Bu nedenle , birleştirme kurallarını özümseyici olarak tanımlarsanız, bir PATCHistek idempotent olabilir .

Idempotent örneği:

// Original resource
{
  name: 'Tito',
  age: 32
}

// PATCH request
{
  age: 33
}

// New resource
{
  name: 'Tito',
  age: 33
}

Belirsiz olmayan örnek:

// Original resource
{
  name: 'Tito',
  age: 32
}

// PATCH request
{
  $increment: 'age'
}

// New resource
{
  name: 'Tito',
  age: 33
}

İkinci örnekte, bir niteliği artırmak için oluşturduğum "Mongo benzeri" sözdizimini kullandım. Açıkçası, bu aynı anlama gelmez, çünkü aynı talebi birden çok kez göndermek, her seferinde farklı sonuçlara yol açacaktır.

Şimdi böyle bir uydurma sözdiziminin kullanılmasının geçerli olup olmadığını merak ediyor olabilirsiniz. Standartlara göre , bu:

PUT ve PATCH istekleri arasındaki fark, sunucunun, Talep URI'si tarafından tanımlanan kaynağı değiştirmek için ekteki varlığı işleme biçimine yansıtılır. Bir PUT isteğinde, ekteki varlık, kaynak sunucuda depolanan kaynağın değiştirilmiş bir sürümü olarak kabul edilir ve müşteri saklanan sürümün değiştirilmesini ister. Bununla birlikte PATCH ile, ekteki varlık, yeni bir sürüm üretmek için o anda sunucuda bulunan bir kaynağın nasıl değiştirilebileceğini açıklayan bir dizi talimat içerir.

Ayrıca, istekleri bu şekilde kullanmanın huzurlu olup olmadığını da merak ediyor olabilirsiniz PATCHve birçok kişi olmadığını düşünüyor, işte bu konu hakkında birçok yorum ile iyi bir cevap .

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.