Jika operasi 'PUT' Tenang mengembalikan sesuatu

437

Saya bertanya-tanya apa pendapat orang tentang PUToperasi yang tenang yang tidak menghasilkan apa-apa (nol) di badan tanggapan.

AwkwardCoder
sumber

Jawaban:

615

Spesifikasi HTTP ( RFC 2616 ) memiliki sejumlah rekomendasi yang berlaku. Inilah interpretasi saya:

  • Kode status HTTP 200 OKuntuk PUT yang berhasil dari pembaruan ke sumber yang ada. Tidak diperlukan badan respons. (Per Bagian 9.6 , 204 No Contentbahkan lebih tepat.)
  • Kode status HTTP 201 Createduntuk PUT yang berhasil dari sumber daya baru, dengan URI yang paling spesifik untuk sumber daya baru dikembalikan di bidang header Lokasi dan semua URI dan metadata sumber daya lain yang relevan yang digema di badan respons. ( RFC 2616 Bagian 10.2.2 )
  • HTTP kode status 409 Conflictuntuk PUT yang tidak berhasil karena 3 rd modifikasi -party, dengan daftar perbedaan antara update berusaha dan sumber daya saat ini dalam tubuh respon. ( RFC 2616 Bagian 10.4.10 )
  • Kode status HTTP 400 Bad Requestuntuk PUT yang gagal, dengan teks berbahasa alami (seperti bahasa Inggris) di badan respons yang menjelaskan mengapa PUT gagal. ( RFC 2616 Bagian 10.4 )
sistem PAUSE
sumber
25
@stian Menarik! Tampaknya agak sombong di pihak Mozilla, karena saya tidak dapat menemukan apa pun di RFC 2616 (terutama bagian 10.2 2xx dan 10.2.1 200 OK yang berhasil ) yang secara khusus mengesampingkan penggunaan 200untuk PUT, DELETE, atau metode lainnya. Apakah saya melewatkan sesuatu? Seperti Mozilla menjadi bos W3 dan IETF? ;) Atau mungkin mereka belum pernah mendengar tentang Prinsip Robustness Postel.
system PAUSE
52
@stian: Kalimat itu dihapus pada 3 Februari 2013. Mungkin karena seseorang membacanya di sini. ;) developer.mozilla.org/en-US/docs/HTTP/…
Christian Strempfer
6
Semantik dari metode PUT adalah untuk mengabaikan kondisi sumber daya saat ini, untuk mengembalikan konflik 409 untuk PUT yang tidak berhasil karena modifikasi pihak ke-3 hanya masuk akal jika permintaan tersebut bersyarat.
Pedro Werneck
8
@systemPAUSE Jawaban yang bagus. Satu poin kecil: jika Anda tidak akan mengembalikan badan respons ke operasi yang sukses, saya sarankan menggunakan 204 secara eksklusif. Beberapa klien (jQuery Ajax, misalnya) akan tersedak jika mereka mengharapkan respons panjang yang tidak nol tetapi tidak mendapatkannya. Anda dapat melihat contohnya di pertanyaan ini .
nick_w
3
Kemungkinan RFC2616 telah diperbarui sejak ini dijawab. Tidak ada di mana dalam 9.6 yang disebutkan No response body neededdalam kaitannya dengan 200. Faktanya, badan respons tidak disebutkan sama sekali sehubungan dengan PUT. Ini hanya menyatakanIf 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

Berbeda dengan sebagian besar jawaban di sini, saya benar-benar berpikir bahwa PUT harus mengembalikan sumber daya yang diperbarui (selain tentu saja kode HTTP).

Alasan mengapa Anda ingin mengembalikan sumber daya sebagai respons untuk operasi PUT adalah karena ketika Anda mengirim representasi sumber daya ke server, server juga dapat menerapkan beberapa pemrosesan ke sumber daya ini, sehingga klien ingin tahu bagaimana sumber daya ini terlihat seperti setelah permintaan selesai dengan sukses. (Jika tidak, ia harus mengeluarkan permintaan GET lain).

LiorH
sumber
3
"server juga dapat menerapkan beberapa pemrosesan pada sumber daya ini": Saya baru ini. Apakah itu benar-benar tenang?
Raedwald
22
@Redwald yakin itu. REST tidak mengharuskan seluruh sumber daya diperbarui pada PUT, meskipun umumnya disarankan. Beberapa bidang mungkin tidak masuk akal untuk memperbarui tanggal yang dibuat atau tanggal modifikasi terakhir, misalnya, mungkin tidak boleh dimasukkan dalam badan PUT, tetapi kemungkinan akan berubah sebagai hasil dari PUT. Yang telah dikatakan, saya tidak setuju dengan LiorH bahwa PUT harus menghasilkan pengembalian sumber daya; Saya akan membutuhkan GET setelah PUT untuk mendapatkan sumber daya yang diperbarui.
Randolpho
19
@Randolpho REST tidak mengharuskan seluruh sumber daya diperbarui pada PUT bukankah ini harus menjadi kasus PATCH?
Marco Ciambrone
14
@MarcoCiambrone Ya, saya setuju dan saya menyangkal komentar saya sebelumnya. Saya telah mengubah lagu saya pada REST dan PUT - PUT harus selalu idempoten dan tidak boleh digunakan untuk pembaruan parsial. POST adalah satu-satunya alternatif kecuali PATCH didukung, dalam hal ini PATCH mungkin merupakan alternatif yang baik. PATCH adalah kata kerja baru, dan mungkin tidak didukung oleh beberapa kerangka kerja sisi server.
Randolpho
2
Jawabannya ditulis jauh sebelum rfc7231, tetapi bagian 4.3.4 memperjelas "Metode PUT meminta status sumber daya target dibuat atau diganti dengan status yang ditentukan oleh representasi yang dilampirkan dalam permintaan pesan payload"
aaaaaa
3

Saya pikir mungkin bagi server untuk mengembalikan konten sebagai tanggapan terhadap PUT. Jika Anda menggunakan format amplop respons yang memungkinkan untuk data yang di-sideload (seperti format yang dikonsumsi oleh data-bara), maka Anda juga dapat menyertakan objek lain yang mungkin telah dimodifikasi melalui pemicu basis data, dll. (Data yang di-sisipkan secara eksplisit untuk mengurangi # permintaan, dan ini sepertinya tempat yang bagus untuk mengoptimalkan.)

Jika saya hanya menerima PUT dan tidak memiliki apa pun untuk melaporkan kembali, saya menggunakan kode status 204 tanpa badan. Jika saya memiliki sesuatu untuk dilaporkan, saya menggunakan kode status 200, dan termasuk badan.

shaunc
sumber
2

The HTTP / 1.1 spec (bagian 9.6) membahas kode respon / kesalahan yang sesuai. Namun itu tidak membahas konten respons.

Apa yang kamu harapkan? Kode respons HTTP sederhana (200 dll.) Tampak langsung dan tidak ambigu bagi saya.

Brian Agnew
sumber
Ya, tetapi bagaimana jika Anda ingin memeriksa apakah data yang dimasukkan ke db setelah PUT atau POST benar-benar mewakili data sebenarnya yang Anda inginkan. Akan lebih baik jika HTTP dapat mengirim kembali tubuh respons.
tnkh
1
@ tnkh apa yang Anda sarankan benar-benar ide yang mengerikan. Buat panggilan GET terpisah setelah pembaruan berhasil untuk mencapai apa yang Anda inginkan. Untuk memastikan kinerja memperkenalkan lapisan caching jika Anda menghadapi masalah di departemen ini. Kami tidak dapat menyelesaikan masalah ini dengan bermain-main dengan logika 'semuanya berjalan'. Jangan main-main dengan prinsip-prinsip pemrograman 'solid' dan dasar yang seharusnya masuk akal di tahun 2020. Ini memalukan!
XDS
@ XDS Saya mengakui bagian pertama dari komentar Anda. Tapi tidak bisa berhenti memutar mataku setelah itu. Komentar yang lucu
tnkh
Terima kasih telah menjelaskan mengapa Anda merasa lucu.
XDS
2

Jika backend dari REST API adalah database relasional SQL, maka

  1. Anda harus memiliki RowVersion di setiap catatan yang dapat diperbarui (untuk menghindari masalah pembaruan yang hilang )
  2. Anda harus selalu mengembalikan salinan catatan baru setelah PUT (untuk mendapatkan RowVersion baru ).

Jika Anda tidak peduli dengan pembaruan yang hilang, atau jika Anda ingin memaksa klien Anda untuk melakukan GET segera setelah PUT, maka jangan kembalikan apa pun dari PUT.

John Henckel
sumber
1

Kode respons Http 201 untuk "Dibuat" bersama dengan header "Lokasi" untuk menunjuk ke tempat klien dapat menemukan sumber daya yang baru dibuat.

dc360
sumber
5
Objek PUT bukan (atau seharusnya tidak) sumber daya yang baru dibuat
kdazzle
9
@kdazzle PUT tentu saja bisa menjadi sumber daya yang baru dibuat, dan seringkali demikian. w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6
Charlie Schliesser
3
Hanya untuk menjelaskan komentar saya sedikit lebih baik. PUT berarti, letakkan item ini di lokasi spesifik ini, menggantikan apa yang saat ini ada (jika ada).
user1751825
3
Benar, "mengganti apa yang ada sekarang" adalah frasa kunci. Seharusnya sudah ada dan sedang diganti. PUT seharusnya tidak untuk menciptakan sumber daya baru.
Kevin M
3
@KevinM Seperti dalam dokumen RFC terbaru rfc7231 , dikatakan bahwa sumber daya dapat dibuat: "Metode PUT meminta status sumber daya target dibuat atau diganti [...]" dan alasan Anda berpikir PUT tidak dapat membuat sumber daya baru adalah karena Anda tidak perlu tahu lokasi sumber daya baru. Tetapi jika Anda tahu lokasi / pengenalnya, itu dapat dibuat jika belum ada.
Leo Lei
0

Saya menggunakan RESTful API di layanan saya, dan ini pendapat saya: Pertama, kita harus mendapatkan pandangan umum :PUTdigunakan untuk memperbarui sumber daya yang tidak dibuat atau didapat.

Saya mendefinisikan sumber daya dengan: Stateless resourcedan Stateful resource:

  • Sumber daya tanpa kewarganegaraan Untuk sumber daya ini, cukup kembalikan HttpCode dengan tubuh kosong, itu sudah cukup.

  • Sumber daya stateful Misalnya: versi sumber daya. Untuk sumber daya semacam ini, Anda harus memberikan versi ketika Anda ingin mengubahnya, jadi kembalikan sumber daya penuh atau kembalikan versi ke klien, sehingga klien tidak perlu mengirim permintaan dapatkan setelah tindakan pembaruan.

Tapi , untuk layanan atau sistem, tetapsimple,clearly,easy to use and maintainadalah hal yang paling penting.

Bruce
sumber
6
"PUT digunakan untuk memperbarui sumber daya yang tidak dibuat atau didapat." - Itu tidak benar atau umum. Secara spesifik, PUT dapat membuat sumber daya. Clear = mengikuti spec yang umum dikenal.
Imre Pühvel
-3

Sama seperti badan Permintaan kosong yang sesuai dengan tujuan asli permintaan GET dan badan tanggapan kosong sesuai dengan tujuan awal permintaan PUT.

AnthonyWJones
sumber
-3

tampaknya baik-baik saja ... meskipun saya akan berpikir indikasi dasar keberhasilan / kegagalan / waktu diposting / # byte yang diterima / dll. akan lebih disukai.

sunting: Saya berpikir sejalan dengan integritas data dan / atau penyimpanan catatan; metadata seperti hash MD5 atau cap waktu untuk waktu yang diterima mungkin berguna untuk file data besar.

Jason S
sumber
1
Bagaimana dengan 200 OK di header respons status? Apakah menurut saya itu cukup untuk mengatakan, "Bekerja dengan baik, terima kasih?"
AnthonyWJones
header respon akan berisi kode status, dan ya kita berbicara tentang HTTP pada saat ini :)
AwkwardCoder
-4

Idealnya itu akan mengembalikan respons sukses / gagal.

cgp
sumber
13
Tidak di badan respons. Kode status HTTP adalah tempat untuk itu. Mungkin jika ada kesalahan beberapa informasi kesalahan yang diperluas dapat dikembalikan dalam penawaran tanggapan
The Archetypal Paul
-4

Ada perbedaan antara tajuk dan isi respons HTTP. PUT seharusnya tidak pernah mengembalikan badan, tetapi harus mengembalikan kode respons di header. Pilih saja 200 jika berhasil, dan 4xx jika tidak. Tidak ada yang namanya kode pengembalian null. Mengapa Anda ingin melakukan ini?

AlexanderJohannesen
sumber