RESTful 'PUT' işlemi bir şey döndürürse


437

İnsanların fikirlerinin PUT, yanıt organında hiçbir şey döndürmeyen (boş) bir RESTful operasyonu hakkında ne olduğunu merak ediyordum .

Yanıtlar:


615

HTTP spesifikasyonunda ( RFC 2616 ) uygulanabilir birkaç öneri vardır. İşte benim yorumum:

  • 200 OKVarolan bir kaynak için başarılı bir güncelleştirme PUT'u için HTTP durum kodu . Yanıt organına gerek yok. ( Bölüm 9.6 uyarınca , 204 No Contentdaha da uygundur.)
  • 201 CreatedKonum üstbilgisi alanında döndürülen yeni kaynak için en belirgin URI ve yanıt gövdesinde yankılanan kaynağın diğer ilgili URI'ları ve meta verileriyle yeni bir kaynağın başarılı PUT'u için HTTP durum kodu . ( RFC 2616 Bölüm 10.2.2 )
  • Deneme güncelleştirmesi ile yanıt gövdesindeki geçerli kaynak arasındaki farkların bir listesi ile 3. taraf bir değişiklik 409 Conflictnedeniyle başarısız olan bir PUT için HTTP durum kodu . ( RFC 2616 Bölüm 10.4.10 )
  • 400 Bad RequestYanıt gövdesinde PUT'un neden başarısız olduğunu açıklayan doğal dil metni (İngilizce gibi) olan başarısız bir PUT için HTTP durum kodu . ( RFC 2616 Bölüm 10.4 )

25
@stian İlginç! RFC 2616'da (özellikle 10.2 Başarılı 2xx ve 10.2.1 200 Tamam ) özellikle 200PUT, DELETE veya başka bir yöntem için kullanımı dışlayan hiçbir şey bulamadığım için Mozilla tarafında oldukça küstah görünüyor . Bir şey mi kaçırdım? Mozilla'nın W3 ve IETF'nin patronu olması gibi mi? ;) Ya da belki de Postel'in Sağlamlık İlkesini hiç duymamışlardır.
sistem DURAKLAT

52
@stian: Bu cümle 3 Şubat 2013'te kaldırıldı. Muhtemelen birisi burada okuduğu için. ;) developer.mozilla.org/tr-TR/docs/HTTP/…
Christian Strempfer

6
PUT yönteminin anlambilimi, kaynağın içinde bulunduğu mevcut durumu göz ardı etmektir, bu nedenle bir 3. taraf değişikliği nedeniyle başarısız olan bir PUT için 409 çakışmasını döndürmek yalnızca istek koşulluysa mantıklıdır.
Pedro Werneck

8
@systemPAUSE Güzel cevap. Küçük bir nokta: Eğer bir yanıt gövdesini başarılı bir operasyona geri döndürmeyecekseniz, sadece 204'ü kullanmanızı öneririm. Bazı istemciler (örneğin, jQuery Ajax), sıfır olmayan bir uzunluk yanıtı beklerlerse ancak almazlarsa boğulurlar. Bu soruda bunun bir örneğini görebilirsiniz .
nick_w

3
Bu yanıtlandığından beri muhtemelen RFC2616 güncellendi. 9.6'da No response body needed200 ile ilgili olarak hiçbir yerde bahsedilmemektedir . Aslında tepki organı bir PUT ile ilgili olarak hiç belirtilmemiştir. Sadece devletlerIf an existing resource is modified, either the 200 (OK) or 204 (No Content) response codes SHOULD be sent to indicate successful completion of the request.
james

164

Buradaki cevapların çoğunun aksine, aslında PUT'un güncellenmiş kaynağı döndürmesi gerektiğini düşünüyorum (elbette HTTP koduna ek olarak).

Kaynağı PUT işlemi için bir yanıt olarak döndürmek istemenizin nedeni, sunucuya bir kaynak temsili gönderdiğinizde, sunucunun da bu kaynağa bazı işlemler uygulayabilmesidir, bu nedenle istemci bu kaynağın nasıl yapıldığını bilmek ister istek başarıyla tamamlandıktan sonra gibi görünebilir. (aksi takdirde başka bir GET isteği yayınlaması gerekir).


3
"sunucu da bu kaynağa bazı işlemler uygulayabilir": Ben bu konuda yeniyim. Gerçekten RESTful mi?
Raedwald

22
@Raedwald olduğundan emin. DİNLENME gerektirmez tüm genellikle önerilir rağmen, kaynak bir PUT güncellenecektir. Bazı alanlar güncelleme yapmak için anlamlı olmayabilir - örneğin, oluşturulmuş tarih veya son değiştirilme tarihi, muhtemelen PUT gövdesine dahil edilmemelidir, ancak muhtemelen PUT sonucunda değişecektir. Bununla birlikte, LiorH ile bir PUT'un kaynağın geri dönüşüyle ​​sonuçlanması gerektiği konusunda hemfikir değilim; Güncellenmiş kaynak elde etmek için PUT sonra bir GET gerekir.
Randolpho

19
@Randolpho REST bir PUT üzerinde tüm kaynağın güncellenmesini gerektirmez, bu bir YAMA durumunda olmamalı mı?
Marco Ciambrone

14
@MarcoCiambrone Evet, katılıyorum ve önceki yorumumu geri alıyorum. REST ve PUT'daki ayarımı değiştirdim - PUT her zaman idempotent olmalı ve asla kısmi bir güncelleme için kullanılmamalıdır. PATCH desteklenmedikçe POST tek alternatiftir, bu durumda PATCH iyi bir alternatif olabilir. Ancak PATCH yeni bir fiildir ve bazı sunucu tarafı çerçeveleri tarafından desteklenmeyebilir.
Randolpho

2
Yanıt rfc7231'den çok önce yazılmıştı, ancak bölüm 4.3.4 , "PUT yöntemi, hedef kaynağın durumunun oluşturulmasını ya da istek iletisi yükünde yer alan temsil tarafından tanımlanan durumla değiştirilmesini istiyor"
aaaaaa

3

Sunucunun bir PUT yanıt olarak içerik döndürmek mümkün olduğunu düşünüyorum. Yandan yüklenen verilere izin veren bir yanıt zarfı biçimi kullanıyorsanız (kor verileri tarafından kullanılan biçim gibi), veritabanı tetikleyicileri vb. Yoluyla değiştirilmiş olabilecek diğer nesneleri de ekleyebilirsiniz (Yandan yüklenen veriler açıkça azaltmak içindir. istek sayısı ve bu, optimize etmek için iyi bir yer gibi görünüyor.)

Sadece PUT'u kabul edersem ve raporlayacak hiçbir şeyim yoksa, beden kodu olmadan 204 durum kodunu kullanırım. Bildirecek bir şeyim varsa, 200 durum kodunu kullanıyorum ve bir gövde ekliyorum.


2

HTTP / 1.1 spektrumu (bölüm 9.6) uygun bir cevap / hata kodları anlatılır. Ancak yanıt içeriğine değinmez.

Ne beklerdiniz? Basit bir HTTP yanıt kodu (200 vb.) Açık ve net görünüyor.


Evet, ancak bir PUT veya POST sonrasında eklenen db'ye veri gerçekten istediğiniz gerçek verileri temsil edip etmediğini kontrol etmek istiyorsanız. HTTP yanıtın gövdesini geri gönderebilirse daha iyi olur.
tnkh

1
@tnkh önerdiğin şey korkunç bir fikir. İstediğinizi başarmak için başarılı bir güncellemeden sonra ayrı bir GET çağrısı yapın. Performansı sağlamak için, bu departmanda sorunlarla karşılaşıyorsanız bir önbellek katmanı tanıtın. Bu sorunları 'her şey gider' mantığıyla uğraşarak çözemeyiz. 2020 yılında sağduyulu olması gereken 'sağlam' ve temel programlama ilkeleriyle uğraşmayın. Bu utanç verici!
XDS

@XDS Yorumun ilk bölümünü kabul ediyorum. Ama bundan sonra gözlerimi yuvarlamak için duramıyorum. Komik yorum
tnkh

Yine de neden komik bulduğunuzu detaylandırdığınız için teşekkürler.
XDS

2

REST API'sinin arka ucu bir SQL ilişkisel veritabanı ise,

  1. güncellenebilecek her kayıtta RowVersion olmalıdır ( kayıp güncelleme probleminden kaçınmak için )
  2. Eğer gereken her zaman yeni bir kopyasını döndürmek (yeni olsun PUT sonra kaydın rowversion ).

Kayıp güncellemeleri umursamıyorsanız veya müşterilerinizi bir PUT'dan hemen sonra bir GET yapmaya zorlamak istiyorsanız, PUT'tan hiçbir şey döndürmeyin.


1

İstemcinin yeni oluşturulan kaynağı nerede bulabileceğini göstermek için "Konum" üstbilgisi ile birlikte "Created" için Http yanıt kodu 201.


5
PUT nesneleri yeni oluşturulan kaynaklar değildir (veya olmamalıdır)
kdazzle

9
@kdazzle PUT kesinlikle yeni oluşturulan bir kaynak olabilir ve çoğu zaman olurdu. w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Charlie Schliesser

3
Sadece yorumumu biraz daha iyi açıklamak için. PUT, şu anda orada olanları (varsa) değiştirerek bu öğeyi bu özel konuma yerleştirin.
user1751825

3
Doğru, "şu anda orada olanı değiştirmek" anahtar kelime. Zaten var olmalı ve değiştiriliyor. PUT yeni kaynaklar oluşturmak için olmamalıdır.
Kevin M

3
@KevinM En son RFC dokümanı rfc7231'de olduğu gibi, kaynakların oluşturulabileceğini söylüyor: "PUT yöntemi, hedef kaynağın durumunun oluşturulmasını veya değiştirilmesini istiyor [...]" ve PUT'un oluşturamayacağını düşündüğünüz neden yeni kaynak, yeni kaynağın yerini mutlaka bilmemenizdir. Ancak konumunu / tanımlayıcısını biliyorsanız, henüz orada değilse oluşturulabilir .
Leo Lei

0

Hizmetlerimde RESTful API kullandım ve işte benim fikrim: Öncelikle ortak bir görüşe geçmeliyiz :PUToluşturma veya almayan bir kaynağı güncellemek için kullanılır.

Kaynakları: Stateless resourceve ile tanımladım Stateful resource:

  • Durumsuz kaynaklar Bu kaynaklar için, HttpCode'u boş bir gövdeyle iade edin, yeterlidir.

  • Durum bilgisi olan kaynaklar Örneğin: kaynağın sürümü. Bu tür kaynaklar için, değiştirmek istediğinizde sürümü sağlamanız gerekir, bu nedenle tam kaynağı döndürün veya sürümü istemciye geri gönderin, böylece istemcinin güncelleme eyleminden sonra bir alma isteği göndermesi gerekmez.

Ama , bir hizmet veya sistem için, bu tutmaksimple,clearly,easy to use and maintainen önemli şeydir.


6
"PUT, oluşturma veya almayan bir kaynağı güncellemek için kullanılır." - bu doğru ya da yaygın değil. Özelliğe göre, PUT kaynağı oluşturabilir. Clear = yaygın olarak bilinen özellikleri takip eder.
Imre Pühvel

-3

Boş bir İstek gövdesinin bir GET isteğinin asıl amacına uygun olması ve boş yanıt gövdesinin bir PUT talebinin asıl amacına uygun olması gibi.


-3

Tamam görünüyor ... gerçi bir başarı / başarısızlık / gönderilen zaman / # bayt alınan / vb bir temel göstergesi düşünüyorum. tercih edilir.

edit: Veri bütünlüğü ve / veya kayıt tutma çizgileri boyunca düşünüyordum; MD5 karması veya alınan zaman için zaman damgası gibi meta veriler büyük veri dosyaları için yardımcı olabilir.


1
Durum yanıtı başlığında yaklaşık 200 OK? "İyi çalıştı teşekkürler" demek için yeterli değil mi?
AnthonyWJones

yanıt başlığı durum kodunu içerir ve evet bu noktada HTTP'den bahsediyoruz :)
AwkwardCoder

-4

İdeal olarak bir başarı / başarısız yanıtı döndürür.


13
Yine de yanıt organında değil. HTTP durum kodu bunun için bir yerdir. Belki bir hata varsa, yanıt teklifinde bazı genişletilmiş hata bilgileri döndürülebilir
Arketipik Paul

-4

HTTP yanıtının başlığı ve gövdesi arasında bir fark vardır. PUT hiçbir zaman bir gövde döndürmemeli, ancak başlıkta bir yanıt kodu döndürmelidir. Başarılı olursa 200'ü, değilse 4xx'i seçin. Boş dönüş kodu diye bir şey yoktur. Bunu neden yapmak istiyorsun?

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.