PUT vs. POST dalam REST

5373

Menurut HTTP / 1.1 Spec:

The POSTmetode yang digunakan untuk permintaan bahwa server asal menerima entitas tertutup di permintaan sebagai subordinat baru sumber daya diidentifikasi oleh Request-URIdiRequest-Line

Dengan kata lain, POSTdigunakan untuk membuat .

The PUTMetode permintaan bahwa entitas tertutup disimpan di bawah disediakan Request-URI. Jika Request-URImerujuk ke sumber daya yang sudah ada, entitas terlampir HARUS dianggap sebagai versi modifikasi dari yang berada di server asal. Jika Request-URItidak menunjuk ke sumber daya yang ada, dan bahwa URI mampu didefinisikan sebagai sumber daya baru oleh agen pengguna yang meminta, server asal dapat membuat sumber daya dengan URI itu. "

Artinya, PUTdigunakan untuk membuat atau mengganti .

Jadi, mana yang harus digunakan untuk membuat sumber daya? Atau seseorang perlu mendukung keduanya?

alex
sumber
56
Mungkin bermanfaat untuk menggunakan definisi dalam HTTPbis - Roy memberikan cukup banyak pekerjaan untuk menjelaskannya. Lihat: tools.ietf.org/html/…
Mark Nottingham
16
Hanya untuk membawa komentar @ MarkNottingham ke revisi terbaru, inilah POST dan PUT , sebagaimana didefinisikan pada HTTPbis.
Marius Butuc
37
Tampak bagi saya bahwa perdebatan ini muncul dari praktik umum penyederhanaan REST dengan menjelaskan Metode HTTP dalam hal operasi CRUD.
Stuporman
5
Sayangnya jawaban pertama salah tentang POST. Periksa jawaban saya untuk penjelasan yang lebih baik tentang perbedaan: stackoverflow.com/a/18243587/2458234
7hi4g0
23
PUT dan POST keduanya metode yang tidak aman. Namun, PUT idempoten, sedangkan POST tidak. - Lihat lebih lanjut di: restcookbook.com/HTTP%20Methods/put-vs-post/…
Dinesh Saini

Jawaban:

4239

Secara keseluruhan:

Baik PUT dan POST dapat digunakan untuk membuat.

Anda harus bertanya, "Anda melakukan tindakan apa?" untuk membedakan apa yang harus Anda gunakan. Anggap Anda sedang merancang API untuk mengajukan pertanyaan. Jika Anda ingin menggunakan POST maka Anda akan melakukannya untuk daftar pertanyaan. Jika Anda ingin menggunakan PUT maka Anda akan melakukannya untuk pertanyaan tertentu.

Hebat keduanya bisa digunakan, jadi mana yang harus saya gunakan dalam desain tenang saya:

Anda tidak perlu mendukung PUT dan POST.

Yang digunakan terserah Anda. Tapi ingatlah untuk menggunakan yang benar tergantung pada objek apa yang Anda referensikan dalam permintaan.

Beberapa pertimbangan:

  • Apakah Anda memberi nama objek URL yang Anda buat secara eksplisit, atau membiarkan server memutuskan? Jika Anda menamai mereka maka gunakan PUT. Jika Anda membiarkan server memutuskan kemudian gunakan POST.
  • PUT idempoten, jadi jika Anda PUT objek dua kali, itu tidak berpengaruh. Ini properti yang bagus, jadi saya akan menggunakan PUT jika memungkinkan.
  • Anda dapat memperbarui atau membuat sumber daya dengan PUT dengan URL objek yang sama
  • Dengan POST, Anda dapat memiliki 2 permintaan masuk sekaligus membuat modifikasi ke URL, dan mereka dapat memperbarui bagian objek yang berbeda.

Sebuah contoh:

Saya menulis berikut ini sebagai bagian dari jawaban lain pada SO mengenai hal ini :

POS:

Digunakan untuk memodifikasi dan memperbarui sumber daya

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

Perhatikan bahwa berikut ini adalah kesalahan:

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

Jika URL belum dibuat, Anda tidak boleh menggunakan POST untuk membuatnya saat menentukan nama. Ini akan menghasilkan kesalahan 'sumber daya tidak ditemukan' karena <new_question>belum ada. Anda harus PUT <new_question> sumber daya di server terlebih dahulu.

Anda bisa melakukan sesuatu seperti ini untuk membuat sumber daya menggunakan POST:

POST /questions HTTP/1.1
Host: www.example.com/

Perhatikan bahwa dalam hal ini nama sumber daya tidak ditentukan, jalur URL objek baru akan dikembalikan kepada Anda.

TARUH:

Digunakan untuk membuat sumber daya, atau menimpanya. Saat Anda menentukan sumber daya URL baru.

Untuk sumber daya baru:

PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/

Untuk menimpa sumber daya yang ada:

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/

Selain itu, dan sedikit lebih ringkas, RFC 7231 Bagian 4.3.4 PUT menyatakan (penekanan ditambahkan),

4.3.4. TARUH

Metode PUT meminta status sumber daya target menjadi createdatau replaceddengan status yang ditentukan oleh representasi terlampir dalam muatan pesan permintaan.

Brian R. Bondy
sumber
1026
Saya pikir orang tidak bisa cukup menekankan fakta bahwa PUT idempoten: jika jaringan rusak dan klien tidak yakin apakah permintaannya berhasil, itu hanya dapat mengirimnya waktu kedua (atau ke-100), dan itu dijamin oleh Spesifikasi HTTP bahwa ini memiliki efek yang persis sama dengan mengirim satu kali.
Jörg W Mittag
77
@ Jörg W Mittag: Tidak perlu. Kedua kalinya dapat mengembalikan 409 Konflik atau sesuatu jika permintaan telah dimodifikasi sementara (oleh beberapa pengguna lain atau permintaan pertama itu sendiri, yang berhasil melewati).
Mitar
632
Jika saya tidak salah, yang harus kami tekankan adalah bahwa PUT didefinisikan sebagai idempoten. Anda masih harus menulis server Anda sedemikian rupa sehingga PUT berperilaku dengan benar, ya? Mungkin lebih baik untuk mengatakan "PUT menyebabkan transportasi dianggap idempotensi, yang dapat mempengaruhi perilaku transportasi, misalnya caching."
Ian Ni-Lewis
150
@ JörgWMittag Idempotence catchphrase? Bagaimana dengan "Kirim dan kirim dan kirim teman saya, pada akhirnya tidak ada bedanya."
James Beninger
39
Anggap mereka sebagai: PUT = masukkan atau perbarui; POST = masukkan. Jadi, ketika Anda membuat dua PUT - Anda mendapatkan satu catatan baru, ketika Anda melakukan dua POST - Anda mendapatkan dua catatan baru.
Eugen Konkov
2218

Anda dapat menemukan pernyataan di web yang mengatakan

Tidak ada yang benar.


Lebih baik memilih antara PUT dan POST berdasarkan idempotence tindakan.

PUT menyiratkan menempatkan sumber daya - sepenuhnya menggantikan apa pun yang tersedia di URL yang diberikan dengan hal yang berbeda. Menurut definisi, PUT adalah idempoten. Lakukan sebanyak yang Anda suka, dan hasilnya sama. x=5idempoten. Anda dapat PUT sumber daya apakah sebelumnya ada, atau tidak (misalnya, untuk Membuat, atau untuk Memperbarui)!

POST memperbarui sumber daya, menambah sumber daya tambahan, atau menyebabkan perubahan. POST bukanlah idempoten, dengan cara yang x++tidak idempoten.


Dengan argumen ini, PUT adalah untuk membuat ketika Anda mengetahui URL dari hal yang akan Anda buat. POST dapat digunakan untuk membuat ketika Anda mengetahui URL "pabrik" atau manajer untuk kategori hal-hal yang ingin Anda buat.

begitu:

POST /expense-report

atau:

PUT  /expense-report/10929
Cheeso
sumber
72
Saya setuju, di mana pun idempotensi terkait, itu harus mengatasi masalah lain karena kesalahan itu dapat menyebabkan banyak bug yang tidak terduga.
Josh
16
Jika POST dapat memperbarui sumber daya, bagaimana itu tidak idempoten? Jika saya mengubah usia siswa menggunakan PUT dan melakukannya 10 kali lipat usia siswa adalah sama jika saya melakukannya sekali.
Jack Ukleja
28
@Schneider, dalam hal ini server Anda berusaha ekstra untuk menjamin idempotensi, tetapi itu bukan iklan. Browser masih akan memperingatkan pengguna jika mereka mencoba memuat ulang permintaan POST tersebut.
Tobu
47
@Schneider POST dapat membuat sumber daya tambahan; maka Anda dapat POST untuk mengumpulkan, seperti POST / laporan pengeluaran dan itu akan membuat sebanyak entitas (laporan pengeluaran) di server Anda sebagai jumlah permintaan yang Anda kirim, bahkan jika mereka benar-benar mirip. Anggap saja memasukkan baris yang sama dalam tabel DB (/ laporan pengeluaran) dengan kunci primer yang ditambahkan secara otomatis. Data tetap sama, kunci (URI dalam hal ini) dihasilkan oleh server dan berbeda untuk setiap sisipan lainnya (permintaan). Jadi, efek POST bisa idempoten, tetapi mungkin juga tidak. Karenanya, POST tidak idempoten.
Snifff
11
Katakanlah kita memiliki entitas yang mungkin memiliki dua properti - namedan date. Jika kita memiliki entitas dengan yang sudah ada namedan date, tetapi kemudian membuat permintaan untuk itu hanya menentukan name, perilaku PUT yang tepat adalah untuk melenyapkan dateentitas tersebut, sedangkan POST dapat memperbarui hanya properti yang ditentukan, meninggalkan properti yang tidak ditentukan sebagaimana adanya. sebelum permintaan dibuat. Apakah itu terdengar benar / masuk akal, atau apakah itu penggunaan PUT yang tidak tepat (saya melihat referensi ke PATCH , yang tampaknya lebih tepat, tetapi belum ada)?
Jon z
707
  • POST ke URL menciptakan sumber daya anak di URL yang ditentukan server .
  • PUT ke URL membuat / mengganti sumber daya secara keseluruhan di URL yang ditentukan klien .
  • PATCH ke URL memperbarui bagian sumber daya di URL yang ditentukan klien itu.

Spesifikasi yang relevan untuk PUT dan POST adalah RFC 2616 §9.5ff.

POST menciptakan sumber daya anak , jadi POST /itemsmenciptakan sumber daya yang hidup di bawah /itemssumber daya. Misalnya. /items/1. Mengirim paket pos yang sama dua kali akan menghasilkan dua sumber daya.

PUT adalah untuk membuat atau mengganti sumber daya di URL yang dikenal oleh klien .

Oleh karena itu: PUT hanya kandidat untuk BUAT di mana klien sudah mengetahui url sebelum sumber daya dibuat. Misalnya. /blogs/nigel/entry/when_to_use_post_vs_putsebagai judul digunakan sebagai kunci sumber daya

PUT menggantikan sumber daya di url yang dikenal jika sudah ada, jadi mengirim permintaan yang sama dua kali tidak berpengaruh. Dengan kata lain, panggilan ke PUT idempoten .

RFC berbunyi seperti ini:

Perbedaan mendasar antara permintaan POST dan PUT tercermin dalam arti berbeda dari Request-URI. URI dalam permintaan POST mengidentifikasi sumber daya yang akan menangani entitas terlampir. Sumber daya itu bisa berupa proses penerimaan data, gateway ke beberapa protokol lain, atau entitas terpisah yang menerima anotasi. Sebaliknya, URI dalam permintaan PUT mengidentifikasi entitas yang dilampirkan dengan permintaan - agen pengguna tahu apa yang dimaksud dengan URI dan server TIDAK HARUS mencoba menerapkan permintaan tersebut ke sumber daya lain. Jika server ingin agar permintaan diterapkan ke URI yang berbeda,

Catatan: PUT sebagian besar telah digunakan untuk memperbarui sumber daya (dengan menggantinya secara keseluruhan), tetapi baru-baru ini ada gerakan menuju menggunakan PATCH untuk memperbarui sumber daya yang ada, karena PUT menentukan bahwa itu menggantikan seluruh sumber daya. RFC 5789.

Pembaruan 2018 : Ada kasus yang dapat dibuat untuk menghindari PUT. Lihat "SISA tanpa PUT"

Dengan teknik “REST without PUT”, idenya adalah bahwa konsumen dipaksa untuk memposting sumber daya permintaan baru 'nounified'. Seperti dibahas sebelumnya, mengubah alamat surat pelanggan adalah POST ke sumber daya baru "ChangeOfAddress", bukan PUT sumber daya "Pelanggan" dengan nilai bidang alamat surat yang berbeda.

diambil dari REST API Design - Resource Modeling oleh Prakash Subramaniam dari Thoughtworks

Ini memaksa API untuk menghindari masalah transisi negara dengan beberapa klien memperbarui satu sumber daya, dan lebih cocok dengan sumber acara dan CQRS. Ketika pekerjaan dilakukan secara serempak, POSTing transformasi dan menunggu untuk diterapkan tampaknya tepat.

Nigel Thorne
sumber
53
Atau dari sisi lain pagar: TETAPKAN jika klien menentukan alamat sumber daya yang dihasilkan, POST jika server melakukannya.
DanMan
3
Saya pikir jawaban ini harus diedit untuk membuatnya lebih jelas apa yang menunjuk @DanMan dengan cara yang sangat sederhana. Apa yang saya temukan paling berharga di sini adalah catatan di bagian akhir, yang menyatakan bahwa PUT harus digunakan hanya untuk mengganti seluruh sumber daya.
Hermes
3
PATCH bukan pilihan realistis untuk setidaknya beberapa tahun, tetapi saya setuju dengan ideologinya.
naksir
4
Saya mencoba memahami, tetapi menggunakan PUT untuk membuat sesuatu hanya akan masuk akal jika klien tahu pasti bahwa sumber daya belum ada, kan? Mengikuti contoh blog, katakan Anda telah membuat ratusan posting blog dalam beberapa tahun, lalu secara tidak sengaja memilih judul yang sama seperti yang Anda lakukan untuk posting dua tahun lalu. Sekarang Anda telah pergi dan mengganti posting itu, yang tidak dimaksudkan. Jadi menggunakan PUT untuk membuat akan membutuhkan klien untuk melacak apa yang diambil dan apa yang tidak, dan dapat menyebabkan kecelakaan dan efek samping yang tidak diinginkan, serta memiliki rute yang melakukan dua hal yang sama sekali berbeda?
galaxyAbtractor
5
Anda benar. MENEMPATKAN posting blog pada url yang sama dengan yang sudah ada akan menyebabkan pembaruan pada posting yang sudah ada (meskipun Anda jelas dapat memeriksa dulu dengan GET). Ini menunjukkan mengapa itu akan menjadi ide yang buruk untuk menggunakan hanya judul sebagai URL. Namun itu akan bekerja di mana saja ada kunci alami dalam data ... yang menurut pengalaman saya jarang. Atau jika Anda menggunakan GUID
Nigel Thorne
221

Ringkasan:

Membuat:

Dapat dilakukan dengan PUT atau POST dengan cara berikut:

TARUH

Menciptakan THE sumber daya baru dengan newResourceId sebagai pengenal, di bawah sumber / URI, atau koleksi .

PUT /resources/<newResourceId> HTTP/1.1 

POS

Menciptakan Sebuah sumber daya baru di bawah / sumber daya URI, atau koleksi . Biasanya pengenal dikembalikan oleh server.

POST /resources HTTP/1.1

Memperbarui:

Dapat hanya dilakukan dengan PUT dengan cara berikut:

TARUH

Memperbarui sumber daya denganResourceId yang ada sebagai pengidentifikasi, di bawah URI / sumber daya, atau koleksi .

PUT /resources/<existingResourceId> HTTP/1.1

Penjelasan:

Ketika berurusan dengan REST dan URI sebagai umum, Anda memiliki generik di sebelah kiri dan spesifik di sebelah kanan . Obat generik biasanya disebut koleksi dan item yang lebih spesifik dapat disebut sumber daya . Perhatikan bahwa sumber daya dapat berisi koleksi .

Contoh:

<- generik - spesifik ->

URI: website.com/users/john
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource

URI:website.com/users/john/posts/23
website.com  - whole site
users        - collection of users
john         - item of the collection, or a resource
posts        - collection of posts from john
23           - post from john with identifier 23, also a resource

Saat Anda menggunakan POST, Anda selalu merujuk ke koleksi , jadi setiap kali Anda mengatakan:

POST /users HTTP/1.1

Anda memposting pengguna baru ke koleksi pengguna .

Jika Anda melanjutkan dan mencoba sesuatu seperti ini:

POST /users/john HTTP/1.1

itu akan berfungsi, tetapi secara semantik Anda mengatakan bahwa Anda ingin menambahkan sumber daya ke koleksi john di bawah koleksi pengguna .

Setelah Anda menggunakan PUT, Anda merujuk ke sumber daya atau item tunggal, mungkin di dalam koleksi . Jadi, ketika Anda mengatakan:

PUT /users/john HTTP/1.1

Anda memberi tahu pembaruan server, atau membuat jika tidak ada, sumber daya john di bawah koleksi pengguna .

Spesifikasi:

Biarkan saya menyoroti beberapa bagian penting dari spesifikasi:

POS

The POST metode yang digunakan untuk permintaan bahwa server asal menerima entitas tertutup di permintaan sebagai baru bawahan dari sumber daya diidentifikasi oleh Request-URI dalam Permintaan-Line

Karenanya, ciptakan sumber daya baru pada koleksi .

TARUH

The PUT metode permintaan bahwa entitas tertutup akan disimpan di bawah disediakan Permintaan-URI. Jika Request-URI mengacu pada sumber daya yang sudah ada , entitas terlampir HARUS dianggap sebagai versi modifikasi dari yang berada di server asal. Jika Request-URI tidak menunjuk ke sumber daya yang ada , dan bahwa URI mampu didefinisikan sebagai sumber daya baru oleh agen pengguna yang meminta, server asal dapat membuat sumber daya dengan URI itu. "

Karenanya, buat atau perbarui berdasarkan keberadaan sumber daya .

Referensi:

7hi4g0
sumber
11
Posting ini sangat membantu saya dalam memahami bahwa POST menambahkan "sesuatu" sebagai anak ke koleksi yang diberikan (URI), sedangkan PUT secara eksplisit mendefinisikan "sesuatu" di lokasi URI yang diberikan.
kwah
3
Ini adalah jawaban terbaik, di sini, saya pikir: tidak ada omong kosong "POST ini dapat memperbarui sumber daya". Saya suka pernyataan Anda, "Pembaruan hanya dapat dilakukan dengan PUT".
Thomas
4
Tidak, PUT bukan untuk memperbarui atau membuat. Ini untuk mengganti. Perhatikan bahwa Anda tidak dapat mengganti apa pun dengan sesuatu untuk efek pembuatan.
thecoshman
2
@ 7hi4g0 PUT adalah untuk memperbarui dengan penggantian yang lengkap, dengan kata lain, itu menggantikan. Anda mengganti apa pun dengan sesuatu, atau sesuatu dengan sesuatu yang sama sekali baru. PUT bukan untuk membuat perubahan kecil (kecuali jika Anda memiliki klien melakukan perubahan kecil dan memberikan seluruh versi baru, bahkan apa yang tetap sama). Untuk modifikasi parsial, PATCH adalah metode pilihan.
thecoshman
1
@ thecoshman Anda bisa, tetapi tidak akan terlalu jelas bahwa buat juga dibahas di sana. Dalam hal ini, lebih baik bersikap eksplisit.
7hi4g0
175

POST berarti "buat baru" seperti pada "Ini adalah input untuk membuat pengguna, buat untuk saya".

PUT berarti "masukkan, ganti jika sudah ada" seperti pada "Ini adalah data untuk pengguna 5".

Anda POSTmencontoh / pengguna karena Anda belum tahu URLtentang pengguna, Anda ingin server membuatnya.

Anda PUTdapat example.com/users/id karena Anda ingin mengganti / membuat pengguna tertentu .

POST dua kali dengan data yang sama berarti membuat dua pengguna yang identik dengan id yang berbeda. MENEMPATKAN dua kali dengan data yang sama membuat pengguna menjadi yang pertama dan memutakhirkannya ke status yang sama untuk kedua kalinya (tidak ada perubahan). Karena Anda berakhir dengan keadaan yang sama setelah PUTberapa kali Anda melakukan itu, dikatakan "sama kuat" setiap kali - idempoten. Ini berguna untuk mencoba ulang permintaan secara otomatis. Tidak ada lagi 'Anda yakin ingin mengirim ulang' saat Anda menekan tombol kembali pada browser.

Saran umum adalah menggunakan POSTketika Anda membutuhkan server untuk mengendalikan URLpembuatan sumber daya Anda. Gunakan PUTsebaliknya. Lebih PUT lebih POST.

Alexander Torstling
sumber
12
Kecerobohan mungkin telah menyebabkan hal itu secara umum diajarkan bahwa hanya ada dua kata kerja yang Anda butuhkan: GET dan POST. DAPATKAN untuk mendapatkan, POST untuk berubah. Bahkan PUT dan DELETE dilakukan menggunakan POST. Bertanya apa arti PUT sebenarnya 25 tahun kemudian mungkin merupakan pertanda bahwa kami telah salah mengartikannya pada awalnya. Popularitas REST mendorong orang kembali ke dasar-dasar di mana kita sekarang harus melepaskan kesalahan masa lalu. POST terlalu sering digunakan dan sekarang diajarkan secara tidak benar. Bagian terbaik: "POSTing dua kali dengan data yang sama berarti membuat dua [sumber] identik". Poin yang bagus!
Maksimal
1
Bagaimana Anda bisa menggunakan PUT untuk membuat catatan dengan ID, seperti dalam contoh Anda user 5jika belum ada? Bukankah maksud Anda update, replace if already exists? atau sesuatu
Luke
@ Coulton: Maksud saya apa yang saya tulis. Anda memasukkan pengguna 5 jika Anda PUT ke / users / 5 dan # 5 belum ada.
Alexander Torstling
@ Coulton: Dan PUTjuga dapat digunakan untuk mengganti nilai sumber daya yang ada secara keseluruhan.
DavidRR
1
"Lebih suka PUT daripada POST" ... peduli untuk membenarkan itu?
thecoshman
173

Saya ingin menambahkan saran "pragmatis" saya. Gunakan PUT ketika Anda tahu "id" dimana objek yang Anda simpan dapat diambil. Menggunakan PUT tidak akan berfungsi dengan baik jika Anda perlu, katakanlah, basis data yang dihasilkan id untuk dikembalikan agar Anda dapat melakukan pencarian atau pembaruan di masa mendatang.

Jadi: Untuk menyimpan pengguna yang ada, atau pengguna yang menghasilkan id dan diverifikasi bahwa id itu unik:

PUT /user/12345 HTTP/1.1  <-- create the user providing the id 12345
Host: mydomain.com

GET /user/12345 HTTP/1.1  <-- return that user
Host: mydomain.com

Jika tidak, gunakan POST untuk awalnya membuat objek, dan PUT untuk memperbarui objek:

POST /user HTTP/1.1   <--- create the user, server returns 12345
Host: mydomain.com

PUT /user/12345 HTTP/1.1  <--- update the user
Host: mydomain.com
Terima kasih
sumber
17
Sebenarnya, seharusnya begitu POST /users. (Perhatikan bahwa /usersitu jamak.) Ini memiliki pengaruh menciptakan pengguna baru dan menjadikannya sumber daya anak dari /userskoleksi.
DavidRR
6
@ DavidvidRR untuk bersikap adil, bagaimana menangani grup adalah debat lain. GET /usersmasuk akal, terbaca seperti yang Anda inginkan, tetapi saya akan baik-baik saja dengan GET /user/<id>atau POST /user(dengan payload untuk kata pengguna baru) karena berbunyi dengan benar 'dapatkan saya pengguna 5' aneh, tetapi 'buat saya pengguna 5' lebih alami. Saya mungkin masih jatuh di sisi pluralisasi :)
thecoshman
126

Gunakan POST untuk membuat, dan PUT untuk memperbarui. Begitulah Ruby on Rails melakukannya.

PUT    /items/1      #=> update
POST   /items        #=> create
Tim Sullivan
sumber
4
POST /itemsmenambahkan item baru ke sumber daya yang sudah didefinisikan ('item'). Itu tidak, seperti jawabannya, "buat grup." Saya tidak mengerti mengapa ini memiliki 12 suara.
David J.
Di luar kotak, Rails tidak mendukung 'membuat grup' melalui REST. Untuk 'membuat grup' yang saya maksud 'buat sumber daya' Anda harus melakukannya melalui kode sumber.
David J.
8
Ini adalah pedoman yang adil, tetapi penyederhanaan yang berlebihan. Seperti yang disebutkan jawaban lainnya, metode mana pun dapat digunakan untuk membuat dan memperbarui.
Brad Koch
2
Saya setuju dengan jawabannya dengan sedikit modifikasi. Gunakan POST untuk membuat dan PUT untuk memperbarui sumber daya sepenuhnya. Untuk pembaruan sebagian, kita dapat menggunakan PUT atau PATCH. Katakanlah kita ingin memperbarui status grup. Kita dapat menggunakan PUT / groups / 1 / status dengan statusnya adalah payload permintaan atau PATCH / groups / 1 dengan rincian tentang tindakan di payload
java_geek
2
Harus juga diperjelas bahwa PUT /items/42ini juga valid untuk membuat sumber daya, tetapi hanya jika klien memiliki hak istimewa untuk menyebutkan sumber daya . (Apakah Rails memberi klien hak istimewa penamaan ini?)
DavidRR
123

Keduanya digunakan untuk transmisi data antara klien ke server, tetapi ada perbedaan halus di antaranya, yaitu:

Masukkan deskripsi gambar di sini

Analogi:

  • PUT yaitu mengambil dan meletakkan di mana itu.
  • POST sebagai mengirim surat di kantor pos .

masukkan deskripsi gambar di sini

Analogi Media / Jaringan Sosial:

  • Posting di media sosial: ketika kami memposting pesan, itu membuat posting baru.
  • Masukkan (mis. Edit) untuk pesan yang sudah kami posting.
Premraj
sumber
21
@MobileMon Tidak, metode REST bukan CRUD.
JLR
1
Saya akan mengatakan PUT untuk UPSER
Hola Soy Edu Feliz Navidad
@MobileMon no: POST ketika Anda membuat sumber daya baru dan Anda tidak tahu titik akhir terakhir untuk mendapatkannya. PUT untuk kasus lain.
Portekoi
67

SISA adalah sangat konsep tingkat tinggi. Bahkan, ia bahkan tidak menyebutkan HTTP sama sekali!

Jika Anda ragu tentang cara mengimplementasikan REST dalam HTTP, Anda selalu dapat melihat spesifikasi Atom Publication Protocol (AtomPub) . AtomPub adalah standar untuk menulis layanan web RESTful dengan HTTP yang dikembangkan oleh banyak tokoh HTTP dan REST, dengan beberapa masukan dari Roy Fielding, penemu REST dan (co-) penemu HTTP sendiri.

Bahkan, Anda bahkan mungkin dapat menggunakan AtomPub secara langsung. Meskipun keluar dari komunitas blogging, itu tidak terbatas pada blogging: itu adalah protokol umum untuk dengan tenang berinteraksi dengan koleksi sewenang-wenang (bersarang) sumber daya sewenang-wenang melalui HTTP. Jika Anda dapat mewakili aplikasi Anda sebagai kumpulan sumber daya yang bersarang, maka Anda bisa menggunakan AtomPub dan tidak khawatir tentang apakah akan menggunakan PUT atau POST, apa yang akan dikembalikan Kode Status HTTP dan semua detailnya.

Inilah yang dikatakan AtomPub tentang penciptaan sumber daya (bagian 9.2):

Untuk menambahkan anggota ke Koleksi, klien mengirim permintaan POST ke URI Koleksi.

Jörg W Mittag
sumber
8
Tidak ada yang salah dengan mengizinkan PUT untuk membuat sumber daya. Perlu diketahui bahwa itu berarti bahwa klien memberikan URL.
Julian Reschke
5
Ada sesuatu yang sangat salah dengan mengizinkan PUT untuk membuat sumber daya: klien menyediakan URL. Itu tugas server!
Joshcodes
@ Joshcodes Tidak selalu merupakan tugas server untuk membuat id klien. Saya semakin sering melihat desain yang memungkinkan klien membuat semacam UUID sebagai id sumber daya. Desain ini cocok untuk meningkatkan skala.
Justin Ohms
@JustinOhms Saya setuju dengan poin Anda tentang ID yang dihasilkan klien (catatan: semua sistem yang dirancang oleh saya sejak sekitar 2008 mengharuskan klien untuk membuat ID sebagai UUID / Panduan). Itu tidak berarti klien harus menentukan URL.
Joshcodes
1
Ya, jika sumber daya sudah ada, gunakan PUT. Namun, dalam hampir semua kasus, sumber daya harus dibuat dengan POST dan klien tidak boleh menyediakan URL. Roy Fielding setuju dengan pernyataan ini FWIW: roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
Joshcodes
61

Keputusan untuk menggunakan PUT atau POST untuk membuat sumber daya pada server dengan HTTP + REST API didasarkan pada siapa yang memiliki struktur URL. Memiliki klien yang tahu, atau berpartisipasi dalam mendefinisikan, struct URL adalah kopling yang tidak perlu seperti kopling yang tidak diinginkan yang muncul dari SOA. Melarikan jenis-jenis kopling adalah alasan REST begitu populer. Oleh karena itu, metode yang tepat untuk digunakan adalah POST. Ada pengecualian untuk aturan ini dan itu terjadi ketika klien ingin mempertahankan kontrol atas struktur lokasi sumber daya yang digunakannya. Ini jarang dan kemungkinan berarti ada sesuatu yang salah.

Pada titik ini beberapa orang akan berpendapat bahwa jika RESTful-URL digunakan, klien mengetahui URL sumber daya dan karenanya PUT dapat diterima. Lagi pula, inilah sebabnya kanonik, dinormalisasi, Ruby on Rails, URL Django penting, lihat API Twitter ... bla bla bla. Orang-orang itu perlu memahami bahwa tidak ada yang namanya URL yang Tenang dan bahwa Roy Fielding sendiri menyatakan bahwa :

API REST tidak boleh mendefinisikan nama sumber daya tetap atau hierarki (penggabungan yang jelas antara klien dan server). Server harus memiliki kebebasan untuk mengontrol namespace mereka sendiri. Sebagai gantinya, izinkan server untuk menginstruksikan klien tentang cara membuat URI yang sesuai, seperti yang dilakukan dalam formulir HTML dan templat URI, dengan menetapkan instruksi tersebut dalam jenis media dan hubungan tautan. [Kegagalan di sini menyiratkan bahwa klien mengasumsikan struktur sumber daya karena informasi out-of band, seperti standar khusus domain, yang setara dengan data yang berorientasi pada penggabungan fungsional RPC].

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

Gagasan RESTful-URL sebenarnya merupakan pelanggaran REST karena server bertanggung jawab atas struktur URL dan harus bebas memutuskan bagaimana menggunakannya untuk menghindari penggandengan. Jika ini membingungkan Anda membaca tentang pentingnya penemuan diri pada desain API.

Menggunakan POST untuk membuat sumber daya hadir dengan pertimbangan desain karena POST tidak idempoten. Ini berarti bahwa mengulang POST beberapa kali tidak menjamin perilaku yang sama setiap kali. Ini membuat orang takut menggunakan PUT untuk membuat sumber daya padahal seharusnya tidak. Mereka tahu itu salah (POST adalah untuk BUAT) tetapi mereka tetap melakukannya karena mereka tidak tahu bagaimana menyelesaikan masalah ini. Kekhawatiran ini ditunjukkan dalam situasi berikut:

  1. Klien POST sumber daya baru ke server.
  2. Server memproses permintaan dan mengirimkan respons.
  3. Klien tidak pernah menerima respons.
  4. Server tidak mengetahui bahwa klien belum menerima respons.
  5. Klien tidak memiliki URL untuk sumber daya (oleh karena itu PUT bukan pilihan) dan mengulangi POST.
  6. POST tidak idempoten dan server ...

Langkah 6 adalah di mana orang biasanya bingung tentang apa yang harus dilakukan. Namun, tidak ada alasan untuk membuat lumpur untuk menyelesaikan masalah ini. Sebaliknya, HTTP dapat digunakan seperti yang ditentukan dalam RFC 2616 dan server membalas:

10.4.10 409 Konflik

Permintaan tidak dapat diselesaikan karena konflik dengan kondisi sumber daya saat ini. Kode ini hanya diperbolehkan dalam situasi di mana diharapkan pengguna dapat menyelesaikan konflik dan mengirimkan kembali permintaan. Badan respons HARUS menyertakan cukup

informasi bagi pengguna untuk mengenali sumber konflik. Idealnya, entitas respons akan mencakup informasi yang cukup bagi pengguna atau agen pengguna untuk memperbaiki masalah; Namun, itu mungkin tidak mungkin dan tidak diperlukan.

Konflik kemungkinan besar terjadi sebagai respons terhadap permintaan PUT. Misalnya, jika versi sedang digunakan dan entitas yang PUT menyertakan perubahan pada sumber daya yang bertentangan dengan yang dibuat oleh permintaan sebelumnya (pihak ketiga), server mungkin menggunakan respons 409 untuk menunjukkan bahwa ia tidak dapat menyelesaikan permintaan . Dalam hal ini, entitas respons kemungkinan akan berisi daftar perbedaan antara dua versi dalam format yang ditentukan oleh Tipe Konten respons.

Membalas dengan kode status 409 Konflik adalah jalan yang benar karena :

  • Melakukan POST data yang memiliki ID yang cocok dengan sumber daya yang sudah ada dalam sistem adalah "konflik dengan kondisi sumber daya saat ini."
  • Karena bagian yang penting adalah agar klien memahami server memiliki sumber daya dan untuk mengambil tindakan yang sesuai. Ini adalah "situasi yang diharapkan bahwa pengguna mungkin dapat menyelesaikan konflik dan mengirim kembali permintaan."
  • Respons yang berisi URL sumber daya dengan ID yang bertentangan dan prasyarat yang sesuai untuk sumber daya akan memberikan "informasi yang cukup bagi pengguna atau agen pengguna untuk memperbaiki masalah" yang merupakan kasus ideal per RFC 2616.

Pembaruan berdasarkan rilis RFC 7231 untuk Ganti 2616

RFC 7231 dirancang untuk menggantikan 2616 dan dalam Bagian 4.3.3 menjelaskan respons yang memungkinkan untuk POST

Jika hasil pemrosesan POST akan setara dengan representasi dari sumber daya yang ada, server asal MUNGKIN mengarahkan agen pengguna ke sumber daya itu dengan mengirimkan respons 303 (Lihat Lainnya) dengan pengidentifikasi sumber daya yang ada di bidang Lokasi. Ini memiliki manfaat memberikan agen pengguna pengidentifikasi sumber daya dan mentransfer representasi melalui metode yang lebih sesuai untuk caching bersama, meskipun dengan biaya permintaan tambahan jika agen pengguna belum memiliki cache di-cache representasi.

Sekarang mungkin tergoda untuk mengembalikan 303 jika POST diulangi. Namun, yang terjadi adalah sebaliknya. Mengembalikan 303 hanya akan masuk akal jika beberapa permintaan membuat (membuat sumber daya yang berbeda) mengembalikan konten yang sama. Contohnya adalah "terima kasih telah mengirimkan pesan permintaan Anda" bahwa klien tidak perlu mengunduh ulang setiap kali. RFC 7231 masih mempertahankan dalam bagian 4.2.2 bahwa POST tidak boleh idempoten dan terus mempertahankan bahwa POST harus digunakan untuk membuat.

Untuk informasi lebih lanjut tentang ini, baca artikel ini .

Kode Josh
sumber
Akankah respons Konflik 409 menjadi kode yang sesuai untuk sesuatu seperti mencoba membuat akun baru dengan nama pengguna yang sudah ada? Saya telah menggunakan 409 untuk konflik versi, tetapi setelah membaca jawaban Anda, saya ingin tahu apakah itu tidak boleh digunakan untuk permintaan "duplikat".
Eric B.
@EricB. Ya, dalam situasi yang Anda gambarkan "karena konflik dengan kondisi sumber daya saat ini" operasi gagal. Selain itu, masuk akal untuk berharap bahwa pengguna dapat menyelesaikan konflik dan badan pesan hanya perlu memberi tahu pengguna bahwa nama pengguna sudah ada.
Joshcodes
@Joshcodes, bisakah Anda mengatakan lebih banyak tentang proses resolusi konflik? Dalam hal ini, jika nama pengguna sudah ada, apakah klien diharapkan untuk meminta pengguna akhir untuk nama pengguna yang berbeda? Bagaimana jika klien benar-benar mencoba menggunakan POST untuk mengubah nama pengguna? Haruskah permintaan PUT masih digunakan untuk memperbarui parameter, sementara POST digunakan untuk membuat objek apakah itu satu per satu atau beberapa? Terima kasih.
BFar
@ BFar2 jika nama pengguna sudah ada maka klien harus meminta pengguna. Untuk mengubah nama pengguna, dengan asumsi nama pengguna adalah bagian dari sumber daya yang sudah dibuat yang perlu dimodifikasi, PUT akan digunakan karena Anda benar, POST digunakan untuk membuat, selalu dan PUT untuk pembaruan.
Joshcodes
menjelaskan hal-hal menggunakan bahasa pendek dan efektif juga merupakan keterampilan yang diinginkan
Junchen Liu
53

Saya suka saran ini, dari definisi PUT RFC 2616 :

Perbedaan mendasar antara permintaan POST dan PUT tercermin dalam arti berbeda dari Request-URI. URI dalam permintaan POST mengidentifikasi sumber daya yang akan menangani entitas terlampir. Sumber daya itu bisa berupa proses penerimaan data, gateway ke beberapa protokol lain, atau entitas terpisah yang menerima anotasi. Sebaliknya, URI dalam permintaan PUT mengidentifikasi entitas yang dilampirkan dengan permintaan - agen pengguna tahu apa yang dimaksud dengan URI dan server TIDAK HARUS mencoba menerapkan permintaan tersebut ke sumber daya lain.

Ini sesuai dengan saran lain di sini, bahwa PUT paling baik diterapkan pada sumber daya yang sudah memiliki nama, dan POST baik untuk membuat objek baru di bawah sumber daya yang ada (dan membiarkan server menamainya).

Saya menafsirkan ini, dan persyaratan idempotensi pada PUT, berarti bahwa:

  • POST baik untuk membuat objek baru di bawah koleksi (dan buat tidak harus idempoten)
  • PUT baik untuk memperbarui objek yang ada (dan pembaruan harus idempoten)
  • POST juga dapat digunakan untuk pembaruan non-idempoten ke objek yang ada (terutama, mengubah bagian dari suatu objek tanpa menentukan semuanya - jika Anda memikirkannya, membuat anggota baru koleksi sebenarnya adalah kasus khusus dari jenis perbarui, dari perspektif koleksi)
  • PUT juga dapat digunakan untuk membuat jika dan hanya jika Anda mengizinkan klien untuk menyebutkan sumber daya. Tetapi karena klien REST tidak seharusnya membuat asumsi tentang struktur URL, ini kurang sesuai dengan yang diinginkan.
metamatt
sumber
3
"POST juga dapat digunakan untuk pembaruan non-idempoten ke objek yang ada (terutama, mengubah bagian dari suatu objek tanpa menentukan semuanya)" Itulah
gunanya
48

Pendeknya:

PUT idempoten, di mana status sumber daya akan sama jika operasi yang sama dijalankan satu kali atau beberapa kali.

POST adalah non-idempoten, di mana keadaan sumber daya dapat menjadi berbeda jika operasi dijalankan beberapa kali dibandingkan dengan mengeksekusi satu kali.

Analogi dengan kueri basis data

PUT Anda dapat memikirkan mirip dengan "UPDATE STUDENT SET address =" abc "di mana id =" 123 ";

POST Anda dapat memikirkan sesuatu seperti "INSERT INTO STUDENT (nama, alamat) VALUES (" abc "," xyzzz ");

Id Pelajar dihasilkan secara otomatis.

Dengan PUT, jika kueri yang sama dijalankan beberapa kali atau satu kali, status tabel STUDENT tetap sama.

Dalam hal POST, jika kueri yang sama dijalankan beberapa kali, beberapa catatan Siswa akan dibuat dalam basis data dan status basis data berubah pada setiap eksekusi kueri "INSERT".

CATATAN: PUT membutuhkan lokasi sumber daya (sudah-sumber daya) di mana pembaruan perlu terjadi, sedangkan POST tidak mengharuskan itu. Karena itu secara intuitif POST dimaksudkan untuk menciptakan sumber daya baru, sedangkan PUT diperlukan untuk memperbarui sumber daya yang sudah ada.

Beberapa mungkin datang dengan pembaruan yang dapat dilakukan dengan POST. Tidak ada aturan keras yang mana yang digunakan untuk pembaruan atau yang digunakan untuk membuat. Sekali lagi ini adalah konvensi, dan secara intuitif saya cenderung dengan alasan yang disebutkan di atas dan mengikutinya.

bharatj
sumber
6
untuk PUT mirip dengan permintaan INSERT atau UPDATE
Eugen Konkov
1
sebenarnya PUT Anda dapat berpikir mirip dengan "UPDATE STUDENT SET address =" abc "di mana id =" 123 "; akan menjadi pernyataan untuk PATCH." UPDATE STUDENT SET address = "abc", name = "newname" di mana id = " 123 "akan menjadi analogi yang benar untuk PUT
mko
Put juga bisa digunakan untuk INSERT. Misalnya jika server Anda mendeteksi Anda mencoba mengunggah file yang sama beberapa kali, itu akan membuat permintaan Anda idempoten. (Tidak ada unggahan file baru yang dilakukan).
kiwicomb123
43

POST seperti mengirim surat ke kotak surat atau memposting email ke antrian email. PUT seperti ketika Anda meletakkan objek di lubang kecil atau tempat di rak (memiliki alamat yang diketahui).

Dengan POST, Anda memposting ke alamat QUEUE atau COLLECTION. Dengan PUT, Anda memasukkan ke alamat ITEM.

PUT idempoten. Anda dapat mengirim permintaan 100 kali dan itu tidak masalah. POST tidak idempoten. Jika Anda mengirim permintaan 100 kali, Anda akan mendapatkan 100 email atau 100 surat di kotak pos Anda.

Aturan umum: jika Anda tahu id atau nama item, gunakan PUT. Jika Anda ingin id atau nama item ditugaskan oleh pihak penerima, gunakan POST.

POST versus PUT

Homer6
sumber
1
Tidak, PUT menyiratkan bahwa Anda mengetahui URL. Jika Anda hanya tahu ID maka POST dengan ID itu untuk mendapatkan URL.
Joshcodes
6
Id adalah bagian dari URL, jadi ya, gunakan PUT jika Anda tahu URL (yang termasuk id).
Homer6
Tidak, URL ditentukan oleh server dan ID belum tentu merupakan bagian dari URL. Roy Fielding akan memberi tahu Anda hal yang sama atau Anda bisa membaca tesisnya .
Joshcodes
@ Joshcodes, apakah itu asumsi REST? Dalam arsitektur RESTful, id item jelas merupakan bagian dari URL, seperti pada: / people / 123. Saya suka situs ini untuk REST: microformats.org/wiki/rest/urls
Beez
1
@ Ya ampun tautan mircoformats menyarankan cara yang baik bagi server untuk menyusun URL mereka tetapi server menentukan URL. Klien hampir tidak pernah melakukannya. Lihat jawaban saya atau artikel terkait jika Anda tidak mengerti ini.
Joshcodes
39

Jawaban baru (sekarang saya mengerti REST dengan lebih baik):

PUT hanyalah pernyataan tentang konten apa yang harus digunakan layanan, mulai sekarang, untuk membuat representasi sumber daya yang diidentifikasi oleh klien; POST adalah pernyataan konten apa yang harus dimiliki layanan, mulai sekarang, (mungkin digandakan) tetapi terserah server cara mengidentifikasi konten itu.

PUT x(jika xmengidentifikasi sumber daya ): "Ganti konten sumber daya yang diidentifikasi xdengan konten saya."

PUT x(jika xtidak mengidentifikasi sumber daya): "Buat sumber daya baru yang mengandung konten dan penggunaan sayax untuk mengidentifikasinya."

POST x: "Simpan konten saya dan beri saya pengenal yang dapat saya gunakan untuk mengidentifikasi sumber daya (lama atau baru) yang mengandung konten tersebut (mungkin dicampur dengan konten lain). Sumber daya yang disebutkan harus identik atau lebih rendah dari yang xdiidentifikasi." " Sumber daya y adalah lebih rendah dari sumber x " biasanya tetapi tidak harus diimplementasikan dengan menjadikan y subpath dari x (misalnya x = /foodan y = /foo/bar) dan memodifikasi representasi (s) dari sumber x untuk mencerminkan keberadaan dari sumber daya baru, misalnya dengan hyperlink ke ySumber daya dan beberapa metadata. Hanya yang terakhir yang benar-benar penting untuk desain yang baik, karena URL tidak jelas di REST - Anda seharusnya menggunakan hypermedia alih-alih konstruksi URL sisi klien untuk melintasi layanan.

Di REST, tidak ada sumber daya yang mengandung "konten". Saya merujuk sebagai "konten" ke data yang digunakan layanan untuk membuat representasi secara konsisten. Biasanya terdiri dari beberapa baris terkait dalam database atau file (misalnya file gambar). Terserah layanan untuk mengubah konten pengguna menjadi sesuatu yang dapat digunakan layanan, misalnya mengubah muatan JSON menjadi pernyataan SQL.

Jawaban asli (mungkin lebih mudah dibaca) :

PUT /something(jika /somethingsudah ada): "Ambil apa pun yang Anda miliki di/something dan gantikan dengan apa yang saya berikan kepada Anda."

PUT /something(jika /somethingbelum ada): "Ambil apa yang kuberikan padamu dan letakkan di situ /something."

POST /something: "Ambil apa yang saya berikan kepada Anda dan letakkan di mana pun Anda inginkan /somethingselama Anda memberi saya URL-nya ketika Anda selesai."

Yordania
sumber
Tetapi bagaimana Anda bisa menggunakan PUT untuk membuat sumber daya baru jika tidak ada, sementara metode pembuatan ID Anda ada pada Peningkatan Otomatis? Biasanya ORM otomatis menghasilkan ID untuk Anda, seperti yang Anda inginkan dalam POST misalnya. Apakah ini berarti bahwa jika Anda ingin menerapkan PUT dengan cara yang benar, Anda harus mengubah pembuatan otomatis id Anda? Ini aneh jika jawabannya adalah ya.
Roni Axelrad
1
@RoniAxelrad: PUT seperti pernyataan database "INSERT OR UPDATE" di mana Anda memasukkan kunci dalam pernyataan, jadi hanya berlaku di mana Anda dapat menjamin tidak ada tabrakan. misalnya. domain Anda memiliki 'kunci alami' atau Anda menggunakan panduan. POST seperti memasukkan ke dalam tabel dengan kunci penambahan otomatis. Anda harus diberitahu oleh database ID apa yang didapat setelah dimasukkan. Perhatikan "INSERT ATAU UPDATE" Anda akan mengganti data sebelumnya jika ada.
Nigel Thorne
@NigelThorne Terima kasih atas jawaban Anda. Jadi jika misalnya saya mencoba PUT buku id 10 dengan URI: PUT buku / 10. Jika id buku 10 tidak ada, saya harus membuat buku dengan id 10 kan? tapi saya tidak bisa mengontrol pembilang ID pembuatan, karena ini peningkatan otomatis. apa yang harus saya lakukan dalam situasi itu?
Roni Axelrad
1
@RoniAxelrad REST PUT ke ID yang tidak ada adalah permintaan ke server untuk membuat sumber daya. Masih tergantung pada server untuk memutuskan apakah ingin mengizinkannya. Server bertanggung jawab. Itu dapat menjawab dengan "Tidak. Aku tidak akan melakukan itu". Anda sudah melakukannya jika pengguna tidak memiliki cukup izin ... dll. Tidak apa-apa bagi server untuk mengatakan "Tidak". REST adalah konvensi yang memungkinkan kami mendefinisikan arti berbagai jenis permintaan ... server Anda memutuskan apa yang harus dilakukan dengan permintaan tersebut berdasarkan logika bisnis Anda :) Bahkan jika dikatakan "tidak", itu masih mengikuti REST :)
Nigel Thorne
38

Jawaban singkat:

Aturan praktis sederhana: Gunakan POST untuk membuat, gunakan PUT untuk memperbarui.

Jawaban panjang:

POS:

  • POST digunakan untuk mengirim data ke server.
  • Berguna saat URL sumber daya tidak dikenal

TARUH:

  • PUT digunakan untuk mentransfer status ke server
  • Berguna saat URL sumber daya diketahui

Jawaban yang lebih panjang:

Untuk memahaminya kita perlu mempertanyakan mengapa PUT diperlukan, masalah apa yang PUT coba selesaikan yang POST tidak bisa.

Dari sudut pandang arsitektur REST tidak ada yang penting. Kita bisa hidup tanpa PUT juga. Tetapi dari sudut pandang pengembang klien itu membuat hidupnya jauh lebih sederhana.

Sebelum PUT, klien tidak dapat secara langsung mengetahui URL yang dihasilkan server atau apakah semua itu menghasilkan atau apakah data yang akan dikirim ke server sudah diperbarui atau belum. PUT membebaskan pengembang dari semua sakit kepala ini. PUT idempoten, PUT menangani kondisi lomba, dan PUT memungkinkan klien memilih URL.

ishandutta2007
sumber
3
Jawaban singkat Anda mungkin SANGAT salah. HTTP PUT gratis diulangi oleh proxy HTTP. Jadi, jika PUT benar-benar melakukan SQL INSERT, itu mungkin gagal untuk kedua kalinya, yang berarti akan mengembalikan hasil yang berbeda sehingga tidak akan menjadi IDEMPOTENT (yang merupakan perbedaan antara PUT dan POST)
Kamil Tomšík
36

Ruby on Rails 4.0 akan menggunakan metode 'PATCH' alih-alih PUT untuk melakukan pembaruan parsial.

RFC 5789 mengatakan tentang PATCH (sejak 1995):

Metode baru diperlukan untuk meningkatkan interoperabilitas dan mencegah kesalahan. Metode PUT sudah didefinisikan untuk menimpa sumber daya dengan badan baru yang lengkap, dan tidak dapat digunakan kembali untuk melakukan perubahan parsial. Kalau tidak, proksi dan cache, dan bahkan klien dan server, dapat menjadi bingung tentang hasil operasi. POST sudah digunakan tetapi tanpa interoperabilitas yang luas (untuk satu, tidak ada cara standar untuk menemukan dukungan format tambalan). PATCH disebutkan dalam spesifikasi HTTP sebelumnya, tetapi tidak sepenuhnya ditentukan.

" Edge Rails: PATCH adalah metode HTTP primer baru untuk pembaruan " menjelaskannya.

germanlinux
sumber
27

Dengan risiko menyatakan kembali apa yang telah dikatakan, tampaknya penting untuk diingat bahwa PUT menyiratkan bahwa klien mengontrol apa yang akan terjadi pada URL , saat membuat sumber daya. Jadi bagian dari pilihan antara PUT dan POST adalah tentang seberapa besar Anda dapat mempercayai klien untuk memberikan URL yang benar dan dinormalisasi yang yang koheren dengan apa pun skema URL Anda.

Ketika Anda tidak dapat sepenuhnya memercayai klien untuk melakukan hal yang benar, akan lebih tepat menggunakan POST untuk membuat item baru dan kemudian mengirim URL kembali ke klien sebagai tanggapan.

pencuri wajan
sumber
2
Saya agak terlambat untuk ini - tetapi seseorang mengatakan sesuatu yang serupa di situs web lain membuatnya mengklik untuk saya. Jika Anda membuat sumber daya dan menggunakan ID yang ditambahkan secara otomatis sebagai "pengidentifikasi" alih-alih nama yang ditetapkan pengguna, itu harus POST.
Ixmatus
2
Ini tidak benar - PUT masih dapat membuat sumber daya dengan mengacu dengan nama non-kanonik, selama di respon, server kembali sebuah Locationheader yang tidak berisi nama sumber daya kanonik.
Eter
1
@Joshcodes jangan lupa bahwa Anda dapat memiliki banyak URI yang merujuk sumber dasar yang sama. Jadi yang dikatakan Ether adalah saran yang bagus, klien dapat PUT ke URL (yang mungkin lebih semantik, seperti PUT /X-files/series/4/episodes/max) dan server merespons dengan URI yang menyediakan tautan unik pendek kanonik ke sumber daya baru (yaitu /X-Ffiles/episodes/91)
thecoshman
@ thecoshman masalahnya adalah masalah struktur URL bukan milik klien. Membaca tentang penemuan diri (juga bagian dari REST) ​​dapat membantu memperjelas hal ini.
Joshcodes
@Joshcodes lalu dengan logika itu, klien tidak boleh menggunakan PUT untuk membuat karena mereka tidak perlu khawatir dengan memberikan URL. Yah ... kecuali server memberikan URL ke PUT jika klien ingin memasukkannya ke ... sesuatu seperti "PUT / komentar / baru" dan server mungkin merespons "204 / komentar / 234532" tetapi itu tampaknya sedikit RPC bagi saya, klien harus POST ke / komentar ...
thecoshman
24

Dengan cara yang sangat sederhana saya mengambil contoh timeline Facebook.

Kasus 1: Ketika Anda memposting sesuatu di timeline Anda, itu adalah entri baru yang baru. Jadi dalam hal ini mereka menggunakan metode POST karena metode POST adalah non-idempoten.

Kasus 2: Jika teman Anda mengomentari kiriman Anda pertama kali, itu juga akan membuat entri baru di database sehingga metode POST digunakan.

Kasus 3: Jika teman Anda mengedit komentarnya, dalam hal ini, mereka memiliki id komentar, sehingga mereka akan memperbarui komentar yang sudah ada alih-alih membuat entri baru dalam database. Karenanya untuk jenis operasi ini gunakan metode PUT karena idempoten. *

Dalam satu baris, gunakan POST untuk menambahkan entri baru dalam database dan PUT untuk memperbarui sesuatu dalam database.

UniCoder
sumber
4
Jika komentar adalah objek dengan properti seperti id pengguna, tanggal dibuat, pesan-komentar, dll. Dan pada saat mengedit hanya komentar-pesan yang diperbarui, PATCH harus dilakukan di sini?
Habeeb Perwad
PUT digunakan oleh FB untuk memperbarui komentar karena sumber daya yang ada sedang diperbarui, dan itulah yang dilakukan PUT (memperbarui sumber daya). PUT kebetulan idempoten, berbeda dengan POST. Kata kerja HTTP menjadi idempoten memengaruhi penanganan kesalahan tetapi tidak menentukan penggunaan. Lihat jawaban saya untuk penjelasan lebih detail: stackoverflow.com/questions/630453/put-vs-post-in-rest/…
Joshcodes
21

Pertimbangan terpenting adalah keandalan . Jika pesan POST hilang, status sistem tidak ditentukan. Pemulihan otomatis tidak mungkin. Untuk pesan PUT, status tidak ditentukan hanya sampai percobaan pertama yang berhasil.

Misalnya, mungkin bukan ide yang baik untuk membuat transaksi kartu kredit dengan POST.

Jika Anda memiliki URI yang dihasilkan secara otomatis di sumber daya Anda, Anda masih dapat menggunakan PUT dengan meneruskan URI yang dihasilkan (menunjuk ke sumber daya kosong) ke klien.

Beberapa pertimbangan lain:

  • POST membatalkan salinan cache dari seluruh sumber daya yang mengandung (konsistensi yang lebih baik)
  • Respons PUT tidak dapat di-cache sementara yang POST adalah (Memerlukan Lokasi-Konten dan kedaluwarsa)
  • PUT kurang didukung oleh mis. Java ME, browser lama, firewall
Hans Malherbe
sumber
Ini salah. Untuk POST, status juga tidak ditentukan hanya sampai percobaan ulang yang berhasil pertama. Kemudian, baik server menerima POST (pesan tidak pernah tiba), melemparkan konflik 409 untuk duplikat ID (pesan tiba, respons hilang), atau respons valid lainnya.
Joshcodes
Secara umum agen pengguna tidak akan dapat dengan aman mencoba kembali operasi POST karena operasi POST tidak memberikan jaminan bahwa dua operasi akan memiliki efek yang sama dengan satu. Istilah "ID" tidak ada hubungannya dengan HTTP. URI mengidentifikasi sumber daya.
Hans Malherbe
Agen pengguna dapat "dengan aman" mencoba kembali operasi POST sebanyak yang diinginkan. Ini hanya akan menerima kesalahan duplikat ID (dengan asumsi sumber daya memiliki ID) atau kesalahan data duplikat (dengan asumsi itu masalah dan sumber daya tidak memiliki ID).
Joshcodes
Poni mengarah ke dinding. HTTP tidak memiliki solusi untuk masalah keandalan, dan ini tidak dipahami dengan baik, tidak banyak dibahas, dan tidak dipenuhi dalam sebagian besar aplikasi web. @Joshcodes Saya punya jawaban untuk pertanyaan ini. Saya pada dasarnya setuju dengan Hans. Ada masalah.
bbsimonbb
@bbsimonbb, HTTP memiliki serangkaian respons kesalahan yang kuat dan terdokumentasi dengan baik. Jawaban saya untuk pertanyaan ini ( stackoverflow.com/questions/630453/put-vs-post-in-rest/… ) mencakup cara menggunakan http sesuai spesifikasi untuk mencapai konsistensi.
Joshcodes
17

Pembaca yang baru mengenal topik ini akan dikejutkan oleh diskusi tanpa akhir tentang apa yang harus Anda lakukan, dan relatif tidak adanya pelajaran dari pengalaman. Fakta bahwa REST "lebih disukai" daripada SOAP adalah, saya kira, pembelajaran tingkat tinggi dari pengalaman, tetapi kebaikan kita pasti telah berkembang dari sana? Ini 2016. Disertasi Roy tahun 2000. Apa yang kami kembangkan? Apakah itu menyenangkan? Apakah mudah diintegrasikan? Mendukung? Apakah ini akan menangani kebangkitan smartphone dan koneksi seluler yang rapuh?

Menurut ME, jaringan kehidupan nyata tidak bisa diandalkan. Permintaan batas waktu. Koneksi diatur ulang. Jaringan mati selama berjam-jam atau berhari-hari. Kereta masuk ke terowongan dengan pengguna seluler naik. Untuk setiap permintaan yang diberikan (seperti yang kadang-kadang diakui dalam semua diskusi ini) permintaan tersebut dapat jatuh ke dalam air dalam perjalanannya, atau responsnya dapat jatuh ke dalam air dalam perjalanan kembali. Dalam kondisi ini, mengeluarkan permintaan PUT, POST dan DELETE langsung terhadap sumber daya substantif selalu membuat saya sedikit brutal dan naif.

HTTP tidak melakukan apa pun untuk memastikan penyelesaian permintaan-respons yang andal, dan itu baik-baik saja karena ini adalah pekerjaan yang benar dari aplikasi yang sadar jaringan. Mengembangkan aplikasi seperti itu, Anda dapat melompat melalui lingkaran untuk menggunakan PUT daripada POST, kemudian lebih banyak lingkaran untuk memberikan jenis kesalahan tertentu pada server jika Anda mendeteksi permintaan duplikat. Kembali ke klien, Anda kemudian harus melewati rintangan untuk menafsirkan kesalahan ini, mengambil ulang, memvalidasi ulang dan memposting ulang.

Atau Anda dapat melakukan ini : anggap permintaan Anda yang tidak aman sebagai sumber daya pengguna tunggal sesaat (sebut saja tindakan). Klien meminta "tindakan" baru pada sumber daya substantif dengan POST kosong ke sumber daya. POST hanya akan digunakan untuk ini. Setelah dengan aman memiliki URI dari tindakan yang baru dicetak, klien PUT permintaan yang tidak aman untuk tindakan URI, bukan sumber daya target . Menyelesaikan tindakan dan memperbarui sumber daya "nyata" adalah pekerjaan API Anda dengan benar, dan di sini dipisahkan dari jaringan yang tidak dapat diandalkan.

Server melakukan bisnis, mengembalikan respons dan menyimpannya terhadap tindakan yang disepakati URI . Jika ada yang tidak beres, klien mengulangi permintaan (perilaku alami!), Dan jika server sudah melihatnya, ia mengulangi respons yang tersimpan dan tidak melakukan hal lain .

Anda akan segera menemukan kesamaan dengan janji: kami membuat dan mengembalikan placeholder untuk hasil sebelum melakukan apa pun. Juga seperti janji, suatu tindakan dapat berhasil atau gagal satu kali, tetapi hasilnya dapat diambil berulang kali.

Yang terbaik dari semuanya, kami memberikan aplikasi pengiriman dan penerimaan kesempatan untuk menghubungkan tindakan yang diidentifikasi secara unik dengan keunikan di lingkungan masing-masing. Dan kita dapat mulai menuntut, dan menegakkan !, perilaku yang bertanggung jawab dari klien: ulangi permintaan Anda sebanyak yang Anda suka, tetapi jangan menghasilkan tindakan baru sampai Anda memiliki hasil yang pasti dari yang sudah ada.

Dengan demikian, banyak masalah pelik hilang. Permintaan memasukkan berulang tidak akan membuat duplikat, dan kami tidak membuat sumber daya yang sebenarnya sampai kami memiliki data. (kolom basis data dapat tetap tidak dapat dibatalkan). Permintaan pembaruan berulang tidak akan mengenai kondisi yang tidak kompatibel dan tidak akan menimpa perubahan berikutnya. Klien dapat (mengambil kembali) dan memproses dengan mulus konfirmasi asli untuk alasan apa pun (klien macet, respons hilang, dll.).

Permintaan penghapusan yang berurutan dapat melihat dan memproses konfirmasi asli, tanpa menemukan kesalahan 404. Jika hal-hal memakan waktu lebih lama dari yang diharapkan, kami dapat merespons sementara, dan kami memiliki tempat di mana klien dapat memeriksa kembali untuk hasil yang pasti. Bagian terbaik dari pola ini adalah properti Kung-Fu (Panda). Kami mengambil kelemahan, kecenderungan bagi klien untuk mengulangi permintaan kapan saja mereka tidak memahami responsnya, dan mengubahnya menjadi kekuatan :-)

Sebelum memberi tahu saya ini bukan RESTful, harap pertimbangkan banyak cara di mana prinsip REST dihormati. Klien tidak membuat URL. API tetap dapat ditemukan, meskipun dengan sedikit perubahan dalam semantik. Kata kerja HTTP digunakan dengan tepat. Jika Anda pikir ini adalah perubahan besar untuk diterapkan, saya dapat memberi tahu Anda dari pengalaman bahwa itu bukan.

Jika Anda berpikir Anda akan memiliki banyak data untuk disimpan, mari kita bicara volume: konfirmasi pembaruan khas adalah sebagian kecil dari satu kilobyte. HTTP saat ini memberi Anda satu atau dua menit untuk merespons secara definitif. Bahkan jika Anda hanya menyimpan aksi selama seminggu, klien memiliki banyak kesempatan untuk mengejar ketinggalan. Jika Anda memiliki volume yang sangat tinggi, Anda mungkin menginginkan penyimpanan nilai kunci yang sesuai dengan asam, atau solusi dalam memori.

bbsimonbb
sumber
1
Tidak akan menyimpan respons seperti memelihara sesi? Yang akan menyebabkan masalah penskalaan (horizontal).
Saurabh Harwande
17

Selain perbedaan yang disarankan oleh orang lain, saya ingin menambahkan satu lagi.

Dalam metode POST Anda dapat mengirim params masukform-data

Dalam metode PUT Anda harus mengirim params masukx-www-form-urlencoded

Header Content-Type:application/x-www-form-urlencoded

Menurut ini, Anda tidak dapat mengirim file atau data multi-bagian dalam metode PUT

EDIT

Jenis konten "application / x-www-form-urlencoded" tidak efisien untuk mengirim sejumlah besar data biner atau teks yang mengandung karakter non-ASCII. Jenis konten "multipart / formulir-data" harus digunakan untuk mengirimkan formulir yang berisi file, data non-ASCII, dan data biner.

Yang berarti jika Anda harus mengirimkan

file, data non-ASCII, dan data biner

Anda harus menggunakan metode POST

Rohit Dhiman
sumber
3
Mengapa ini tidak dibenarkan? Jika benar, ini adalah perbedaan kritis bukan?
Iofacture
2
Saya menghadapinya ketika menerapkan API untuk pembaruan profil, yang mencakup pengunggahan gambar profil pengguna. Kemudian saya mengujinya dengan tukang pos, Ajax, PHP curl dan laravel 5.6 sebagai backend.
Rohit Dhiman
14

Tampaknya selalu ada beberapa kebingungan kapan harus menggunakan HTTP POST versus metode HTTP PUT untuk layanan REST. Sebagian besar pengembang akan mencoba mengaitkan operasi CRUD secara langsung dengan metode HTTP. Saya akan berpendapat bahwa ini tidak benar dan kita tidak bisa begitu saja mengasosiasikan konsep CRUD dengan metode HTTP. Itu adalah:

Create => HTTP PUT
Retrieve => HTTP GET
Update => HTTP POST
Delete => HTTP DELETE

Memang benar bahwa R (etrieve) dan D (elete) dari operasi CRUD dapat dipetakan langsung ke metode HTTP GET dan DELETE masing-masing. Namun, kebingungannya terletak pada operasi C (reate) dan U (update). Dalam beberapa kasus, seseorang dapat menggunakan PUT untuk membuat sementara dalam kasus lain POST akan diperlukan. Ambiguitas terletak pada definisi metode HTTP PUT versus metode HTTP POST.

Menurut spesifikasi HTTP 1.1, metode GET, HEAD, DELETE, dan PUT harus idempoten, dan metode POST tidak idempoten. Artinya, suatu operasi idempoten jika dapat dilakukan pada sumber daya sekali atau berkali-kali dan selalu mengembalikan keadaan yang sama dari sumber daya itu. Sedangkan operasi non idempoten dapat mengembalikan keadaan sumber daya yang dimodifikasi dari satu permintaan ke permintaan lainnya. Karenanya, dalam operasi non idempoten, tidak ada jaminan bahwa seseorang akan menerima kondisi sumber daya yang sama.

Berdasarkan definisi idempoten di atas, pendapat saya tentang menggunakan metode HTTP PUT versus menggunakan metode HTTP POST untuk layanan REST adalah: Gunakan metode HTTP PUT ketika:

The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee.
The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date).

Dalam kedua kasus, operasi ini dapat dilakukan beberapa kali dengan hasil yang sama. Itu adalah sumber daya tidak akan diubah dengan meminta operasi lebih dari sekali. Oleh karena itu, operasi idempoten sejati. Gunakan metode HTTP POST ketika:

The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client.
On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation.

Kesimpulan

Jangan langsung mengkorelasikan dan memetakan operasi CRUD ke metode HTTP untuk layanan REST. Penggunaan metode HTTP PUT versus metode HTTP POST harus didasarkan pada aspek idempoten dari operasi itu. Artinya, jika operasi idempoten, maka gunakan metode HTTP PUT. Jika operasi ini bukan idempoten, maka gunakan metode HTTP POST.

Burhan
sumber
2
Perbarui => HTTP POST: POST bukan untuk memperbarui
Premraj
@premraj Anda membuat asumsi bahwa Burhan mengatakan kepada Anda untuk tidak membuat; yaitu, Anda sedang mengkonfigurasi CRUD, REST, dan HTTP. Jika Anda membaca RFC 7231, di mana hal-hal ini didefinisikan, Anda akan menemukan bahwa dalam protokol HTTP, definisi POST tentu memungkinkan pembaruan. Hanya kendala REST yang mengatakan sebaliknya.
IAM_AL_X
13

server asal dapat membuat sumber daya dengan URI itu

Jadi Anda menggunakan POST dan mungkin, tetapi PUT tidak perlu untuk pembuatan sumber daya. Anda tidak harus mendukung keduanya. Bagi saya POST sudah cukup sempurna. Jadi itu adalah keputusan desain.

Seperti kutipan Anda sebutkan, Anda menggunakan PUT untuk membuat tidak ada sumber daya yang ditetapkan untuk IRI, dan Anda tetap ingin membuat sumber daya. Misalnya, PUT /users/123/passwordbiasanya mengganti kata sandi lama dengan yang baru, tetapi Anda dapat menggunakannya untuk membuat kata sandi jika kata sandi tersebut belum ada (misalnya, oleh pengguna yang baru terdaftar atau dengan mengembalikan pengguna yang diblokir).

inf3rno
sumber
Saya pikir Anda telah berhasil memberikan salah satu dari beberapa contoh bagus tentang cara menggunakan PUT, dilakukan dengan baik.
thecoshman
12

Saya akan mendarat dengan yang berikut:

PUT mengacu pada sumber daya, yang diidentifikasi oleh URI. Dalam hal ini, Anda memperbaruinya. Ini adalah bagian dari tiga kata kerja yang merujuk pada sumber daya - hapus dan menjadi dua lainnya.

POST pada dasarnya adalah pesan bentuk bebas, dengan artinya didefinisikan 'out of band'. Jika pesan dapat diartikan sebagai menambahkan sumber daya ke direktori, itu tidak masalah, tetapi pada dasarnya Anda perlu memahami pesan yang Anda kirim (posting) untuk mengetahui apa yang akan terjadi dengan sumber daya.


Karena PUT dan DAPATKAN dan HAPUS merujuk ke sumber daya, mereka juga menurut definisi idempoten.

POST dapat melakukan tiga fungsi lainnya, tetapi kemudian semantik permintaan akan hilang pada perantara seperti cache dan proxy. Ini juga berlaku untuk memberikan keamanan pada sumber daya, karena URI posting tidak selalu menunjukkan sumber daya yang diterapkannya (meskipun dapat).

A PUT tidak perlu menjadi sebuah ciptaan; layanan dapat error jika sumber daya belum dibuat, tetapi jika tidak perbarui. Atau sebaliknya - mungkin membuat sumber daya, tetapi tidak mengizinkan pembaruan. Satu-satunya hal yang diperlukan tentang PUT adalah bahwa ia menunjuk ke sumber daya tertentu, dan muatannya adalah representasi dari sumber daya itu. PUT yang berhasil berarti (mencegah gangguan) bahwa GET akan mengambil sumber daya yang sama.


Sunting: Satu hal lagi - seorang PUT dapat membuat, tetapi jika itu dilakukan maka ID tersebut harus merupakan ID alami - AKA alamat email. Dengan begitu ketika Anda PUT dua kali, put kedua adalah pembaruan yang pertama. Ini membuatnya idempoten .

Jika ID dibuat (misalnya ID karyawan baru), maka PUT kedua dengan URL yang sama akan membuat catatan baru, yang melanggar aturan idempoten. Dalam hal ini kata kerjanya adalah POST, dan pesannya (bukan sumber daya) adalah membuat sumber daya menggunakan nilai-nilai yang didefinisikan dalam pesan ini.

Gerard ONeill
sumber
9

Semantiknya seharusnya berbeda, dalam "PUT", seperti "GET" seharusnya idempoten - artinya, Anda dapat meminta PUT persis sama beberapa kali dan hasilnya akan seolah-olah Anda hanya mengeksekusi sekali.

Saya akan menjelaskan tentang konvensi yang menurut saya paling banyak digunakan dan paling berguna:

Ketika Anda PUT sumber daya di URL tertentu yang terjadi adalah bahwa itu harus disimpan di URL itu, atau sesuatu di sepanjang baris itu.

Ketika Anda POST ke sumber daya di URL tertentu, seringkali Anda memposting informasi terkait ke URL itu. Ini menyiratkan bahwa sumber daya di URL sudah ada.

Misalnya, ketika Anda ingin membuat aliran baru, Anda dapat PUT ke beberapa URL. Tetapi ketika Anda ingin POST pesan ke aliran yang ada, Anda POST ke URL-nya.

Sedangkan untuk memodifikasi properti stream, Anda dapat melakukannya dengan PUT atau POST. Pada dasarnya, hanya gunakan "PUT" ketika operasi idempoten - jika tidak gunakan POST.

Perhatikan, bagaimanapun, bahwa tidak semua browser modern mendukung kata kerja HTTP selain GET atau POST.

Gregory Magarshak
sumber
Apa yang Anda gambarkan sebagai POST sebenarnya adalah bagaimana PATCH harus bersikap. POST seharusnya berarti sesuatu yang lebih mirip dengan "menambahkan" seperti pada "posting ke milis".
Alexander Torstling
8

Sebagian besar waktu, Anda akan menggunakannya seperti ini:

  • POST sumber ke koleksi
  • PUT sumber daya yang diidentifikasi oleh collection /: id

Sebagai contoh:

  • POST / barang
  • PUT / item / 1234

Dalam kedua kasus, badan permintaan berisi data untuk sumber daya yang akan dibuat atau diperbarui. Seharusnya jelas dari nama rute bahwa POST tidak idempoten (jika Anda menyebutnya 3 kali itu akan membuat 3 objek), tetapi PUT adalah idempoten (jika Anda memanggilnya 3 kali hasilnya sama). PUT sering digunakan untuk operasi "aktif" (buat atau perbarui), tetapi Anda selalu dapat mengembalikan kesalahan 404 jika Anda hanya ingin menggunakannya untuk memodifikasi.

Perhatikan bahwa POST "membuat" elemen baru dalam koleksi, dan PUT "mengganti" elemen pada URL yang diberikan, tetapi itu adalah praktik yang sangat umum untuk menggunakan PUT untuk modifikasi sebagian, yaitu, menggunakannya hanya untuk memperbarui sumber daya yang ada dan hanya memodifikasi bidang yang disertakan dalam tubuh (mengabaikan bidang lainnya). Ini secara teknis salah, jika Anda ingin menjadi REST-purist, PUT harus mengganti seluruh sumber daya dan Anda harus menggunakan PATCH untuk pembaruan parsial. Saya pribadi tidak terlalu peduli sejauh perilakunya jelas dan konsisten di semua titik akhir API Anda.

Ingat, REST adalah seperangkat konvensi dan pedoman untuk menjaga API Anda tetap sederhana. Jika Anda berakhir dengan penyelesaian yang rumit hanya untuk mencentang kotak "RESTfull" maka Anda mengalahkan tujuannya;)

tothemario
sumber
7

Meskipun mungkin ada cara agnostik untuk menggambarkan ini, tampaknya bertentangan dengan berbagai pernyataan dari jawaban situs web.

Mari kita menjadi sangat jelas dan langsung ke sini. Jika Anda seorang pengembang .NET yang bekerja dengan Web API, faktanya adalah (dari dokumentasi Microsoft API), http://www.asp.net/web-api/overview/creating-web-apis/creating-a-web -api-that-support-crud-operations :

1. PUT = UPDATE (/api/products/id)
2. MCSD Exams 2014 -  UPDATE = PUT, there are **NO** multiple answers for that question period.

Tentu Anda "dapat" menggunakan "POST" untuk memperbarui, tetapi cukup ikuti konvensi yang ditetapkan untuk Anda dengan kerangka kerja yang Anda berikan. Dalam kasus saya ini adalah .NET / Web API, jadi PUT untuk UPDATE tidak ada perdebatan.

Saya harap ini membantu setiap pengembang Microsoft yang membaca semua komentar dengan tautan situs web Amazon dan Sun / Java.

Tom Stickel
sumber
7

Ini aturan sederhana:

PUT ke URL harus digunakan untuk memperbarui atau membuat sumber daya yang dapat ditemukan di URL itu.

POST ke URL harus digunakan untuk memperbarui atau membuat sumber daya yang terletak di beberapa URL ("bawahan") lainnya, atau tidak dapat ditemukan melalui HTTP.

Adam Griffiths
sumber
1
PUT bukan untuk pembaruan, itu untuk mengganti, perhatikan bahwa untuk membuat Anda mengganti apa pun dengan sesuatu. POST sama sekali tidak untuk pembaruan dalam bentuk apa pun.
thecoshman
2
Apakah spec http mengatakan itu? Atau apakah Anda mendasarkan komentar Anda pada sesuatu yang lain?
Adam Griffiths
Itu hanya akal sehat, bagaimana Anda memperbarui sesuatu ketika Anda tidak tahu apa yang sedang Anda perbarui? POST adalah untuk menciptakan sumber daya baru.
thecoshman
2
thecoshman - Anda menyalahgunakan semantik di sini - pengganti dapat menjadi pembaruan jika sumber daya yang sama dengan beberapa perbedaan. Pengganti hanya valid untuk put jika ganti digunakan untuk mengubah sumber yang sama. Mengganti dengan sumber daya baru dan berbeda tidak valid (hapus yang lama dan tambahkan baru?), Terutama jika sumber daya 'baru' tidak memiliki ID alami. POST, OTOH, adalah sesuatu yang dapat membuat, memperbarui, mengganti, dan menghapus - menggunakan posting tergantung pada ada atau tidaknya pesan untuk ditafsirkan, seperti 'terapkan diskon', yang mungkin atau tidak dapat mengubah sumber daya tergantung pada logika.
Gerard ONeill
Adapun komentar kedua Anda - bagaimana kalau Anda 'mendapatkan' sumber daya, memodifikasi bidang yang Anda butuhkan, dan kemudian mengembalikannya? Atau bagaimana jika sumber daya berasal dari sumber yang berbeda tetapi menggunakan ID alami (ID eksternal) - put akan secara alami memperbarui sumber daya di URL ketika data asli berubah.
Gerard ONeill
6

Jika Anda terbiasa dengan operasi basis data, ada

  1. Pilih
  2. Memasukkan
  3. Memperbarui
  4. Menghapus
  5. Gabung (Perbarui jika sudah ada, sisipkan lain)

Saya menggunakan PUTuntuk Gabung dan memperbarui operasi seperti dan gunakan POSTuntuk Penyisipan.

Rajan
sumber
5

Dalam praktiknya, POST bekerja dengan baik untuk menciptakan sumber daya. URL sumber daya yang baru dibuat harus dikembalikan di header respons Lokasi. PUT harus digunakan untuk memperbarui sumber daya sepenuhnya. Harap mengerti bahwa ini adalah praktik terbaik saat merancang API RESTful. Spesifikasi HTTP tidak membatasi penggunaan PUT / POST dengan beberapa batasan untuk membuat / memperbarui sumber daya. Lihatlah http://techoctave.com/c7/posts/71-twitter-rest-api-dissected yang merangkum praktik terbaik.

java_geek
sumber
Sebagian besar, dari membaca semua keributan ini, Anda tampak tertarik. Saya akan mengatakan, kita harus merujuk ke PUT sebagai metode ganti, daripada membuat / memperbarui. Saya pikir itu lebih baik menggambarkan dalam satu apa yang dilakukannya.
thecoshman