Apa kode respons REST yang tepat untuk permintaan yang valid selain data yang kosong?

332

Misalnya Anda menjalankan permintaan GET untuk users/9tetapi tidak ada pengguna dengan id # 9. Kode respon terbaik mana?

  • 200 OK
  • 202 Diterima
  • 204 Tidak Ada Konten
  • 400 permintaan Buruk
  • 404 tidak ditemukan
IMB
sumber
19
Petunjuk: Apakah Anda menemukan Pengguna 9?
Chris Pfohl
42
Petunjuk 2: Jadi pengguna 9 tidak ditemukan ?
Tomasz Nurkiewicz
18
@ BNI siapa yang mengatakan 204? "Tidak Ada Konten" menunjukkan bahwa entitas yang Anda cari ada, tetapi tidak memiliki representasi. Misalnya, jika blog dengan id 15 tidak memiliki komentar, dan Anda tidak ingin mengembalikan daftar kosong untuk komentar blog nomor 15: "/ blog / 15 / komentar" akan mengembalikan NoContent. Di sisi lain jika blog 15 ada, '404 Not Found' lebih tepat.
Chris Pfohl
12
@Crisfole bukan maksud Anda ". Di sisi lain, jika blog 15 tidak ada, '404 Not Found' lebih tepat"
gdoron mendukung Monica
15
Saya pasti melakukan @gdoron! :) Terima kasih. Sayangnya saya terlambat sekitar tiga tahun untuk mengeditnya dan memperbaikinya.
Chris Pfohl

Jawaban:

249

TL; DR: Gunakan 404

Lihat Blog Ini . Ini menjelaskan dengan sangat baik.

Ringkasan komentar blog tentang 204:

  1. 204 No Content tidak terlalu berguna sebagai kode respons untuk peramban (meskipun menurut peramban spesifikasi HTTP, Anda perlu memahaminya sebagai kode respons 'jangan ubah tampilan').
  2. 204 No Content adalah Namun, sangat berguna untuk layanan web ajax yang mungkin ingin menunjukkan keberhasilan tanpa harus kembali sesuatu. (Terutama dalam kasus seperti DELETEatau POSTyang tidak memerlukan umpan balik).

Jawabannya, oleh karena itu, untuk pertanyaan Anda digunakan 404dalam kasus Anda. 204adalah kode respons khusus yang tidak boleh sering Anda kembali ke browser sebagai tanggapan atas a GET.

Kode respons lain yang bahkan kurang sesuai daripada 204dan 404:

  1. 200harus dikembalikan dengan tubuh apa pun yang berhasil Anda ambil. Tidak tepat ketika entitas yang Anda ambil tidak ada.
  2. 202digunakan ketika server sudah mulai bekerja pada suatu objek tetapi objek belum sepenuhnya siap. Tentu tidak demikian di sini. Anda belum memulai, Anda juga tidak akan memulai, konstruksi pengguna 9 dalam menanggapi GETpermintaan. Itu melanggar segala macam aturan.
  3. 400digunakan sebagai tanggapan atas permintaan HTTP yang diformat dengan buruk (misalnya header http salah format, segmen yang dipesan salah, dll). Ini hampir pasti akan ditangani oleh kerangka apa pun yang Anda gunakan. Anda tidak harus berurusan dengan ini kecuali Anda menulis server sendiri dari awal. Sunting : RFC yang lebih baru sekarang memungkinkan 400 digunakan untuk permintaan yang secara semantik tidak valid.

Deskripsi Wikipedia tentang kode status HTTP sangat membantu. Anda juga dapat melihat definisi dalam dokumen HTTP / 1.1 RFC2616 di www.w3.org

Chris Pfohl
sumber
8
Catatan: kode respons di tahun 200-an menunjukkan keberhasilan. Kode respons di tahun 400-an menunjukkan kegagalan. Ringkasan, poin satu dan dua, adalah tentang 204kode respons (Tidak Ada Konten).
Chris Pfohl
227
-1 karena saya juga sangat menentang 404 sebagai respons terhadap panggilan sukses yang tidak memiliki catatan untuk dikembalikan. Sebagai pengembang yang berurusan dengan API untuk aplikasi non-web, saya telah menghabiskan waktu berjam-jam untuk menghubungi pengembang API untuk melacak mengapa titik akhir API yang saya panggil tidak ada, padahal sebenarnya itu terjadi, itu hanya tidak memiliki data untuk dilaporkan. Sehubungan dengan 204 yang tidak terlalu berguna untuk browser, itu agak seperti ekor mengibas-ngibaskan anjing karena sebagian besar penggunaan titik akhir API di semesta perangkat pintar kita bukan berbasis browser dan yang kemungkinan menggunakan AJAX. Maaf untuk mengambil poin.
Matt Cashatt
38
@MatthewPatrickCashatt Anda bebas untuk downvote sesuka Anda. Saya sekarang akhirnya mengerti mengapa orang-orang merendahkan saya, tetapi alasannya masih salah. Ketika menerima 404 itu tidak berarti rute itu tidak masuk akal, itu berarti tidak ada sumber daya di lokasi itu. Titik. Ini benar jika Anda meminta /badurlatau /user/9ketika pengguna seperti itu tidak ada. Pengembang dapat membantu dengan menambahkan frasa alasan yang lebih baik daripada 'Tidak Ditemukan', tetapi tidak diharuskan.
Chris Pfohl
19
@Crisfole Saya cenderung tidak setuju (meskipun tidak downvote, terus membaca), didasarkan pada definisi W3 dari 404 , khususnya The server has not found anything matching the Request-URI. Server web / aplikasi sebenarnya telah menemukan AKSI yang cocok dengan Request-URI, meskipun server db belum. Namun, itu juga mengatakan This status code is commonly used when [...] no other response is applicable, jadi saya pikir itu memvalidasi penggunaannya agak (bahkan jika saya tidak setuju dengan / menyukainya).
Daevin
8
Saya tidak berpikir Anda menyinggung poin yang saya sampaikan: 404 berbahaya membingungkan. Mengandalkan penelepon yang memeriksa frasa alasan atau isi dari respons berarti Anda tidak mempercayai kode status, dalam hal ini tidak berguna.
Adrian Baker
364

Saya sangat menentang 404 yang mendukung 204 atau 200 dengan data kosong. Atau setidaknya satu harus menggunakan entitas respons dengan 404.

Permintaan diterima dan diproses dengan benar - itu memang memicu kode aplikasi di server, sehingga orang tidak bisa benar-benar mengatakan bahwa itu adalah kesalahan klien dan dengan demikian seluruh kelas kode kesalahan klien (4xx) tidak pas.

Lebih penting lagi, 404 dapat terjadi karena sejumlah alasan teknis. Misalnya aplikasi yang sementara dinonaktifkan atau dihapus pada server, masalah koneksi proxy dan yang lainnya. Oleh karena itu klien tidak dapat membedakan antara 404 yang berarti "set hasil kosong" dan 404 yang berarti "layanan tidak dapat ditemukan, coba lagi nanti".

Ini bisa berakibat fatal: Bayangkan layanan akuntansi di perusahaan Anda yang mencantumkan semua karyawan yang mendapat bonus tahunan. Sayangnya, suatu saat ketika disebut mengembalikan 404. Apakah itu berarti bahwa tidak ada yang jatuh tempo untuk bonus, atau bahwa aplikasi saat ini sedang down untuk penyebaran baru?

-> Untuk aplikasi yang peduli dengan kualitas data mereka, 404 tanpa entitas respon oleh karena itu cukup banyak yang tidak bisa digunakan.

Juga, banyak kerangka kerja klien merespons 404 dengan melemparkan pengecualian tanpa ada pertanyaan lebih lanjut. Ini memaksa pengembang klien untuk menangkap pengecualian itu, untuk mengevaluasinya, dan kemudian memutuskan berdasarkan apakah akan mencatatnya sebagai kesalahan yang diambil oleh misalnya komponen pemantauan atau apakah akan mengabaikannya. Bagi saya itu juga tampaknya tidak cantik.

Keuntungan 404 lebih dari 204 adalah dapat mengembalikan entitas respons yang mungkin berisi beberapa informasi tentang mengapa sumber daya yang diminta tidak ditemukan. Tetapi jika itu benar-benar relevan, maka orang juga dapat mempertimbangkan untuk menggunakan respons 200 OK dan merancang sistem dengan cara yang memungkinkan respons kesalahan dalam data payload. Atau, seseorang dapat menggunakan payload dari respons 404 untuk mengembalikan informasi terstruktur kepada pemanggil. Jika ia menerima misalnya halaman html alih-alih XML atau JSON yang dapat diuraikan, maka itu merupakan indikator yang baik bahwa ada kesalahan teknis alih-alih jawaban "tidak ada hasil" yang mungkin valid dari sudut pandang pemanggil. Atau orang dapat menggunakan header respons HTTP untuk itu.

Namun saya lebih suka 204 atau 200 dengan respon kosong. Dengan cara itu status pelaksanaan teknis permintaan dipisahkan dari hasil logis permintaan. 2xx berarti "eksekusi teknis ok, ini hasilnya, tangani".

Saya pikir dalam banyak kasus itu harus diserahkan kepada klien untuk memutuskan apakah hasil kosong dapat diterima atau tidak. Dengan mengembalikan 404 tanpa entitas respons meskipun eksekusi teknis yang benar, klien dapat memutuskan untuk menganggap kasus sebagai kesalahan yang tidak ada kesalahan.

Analogi cepat lain: Mengembalikan 404 untuk "tidak ada hasil yang ditemukan" adalah seperti melempar DatabaseConnectionException jika kueri SQL tidak mengembalikan hasil. Itu bisa menyelesaikan pekerjaan, tetapi ada banyak kemungkinan penyebab teknis yang melemparkan pengecualian yang sama yang kemudian akan keliru untuk hasil yang valid.

Jens Wurm
sumber
30
Alasan teknis untuk 'tidak ditemukan' juga dikenal sebagai kesalahan server. Itu harus di tahun 500-an. Secara khusus: "Layanan tidak dapat ditemukan" adalah 503 Service Unavailable.
Chris Pfohl
43
Penanya juga bertanya tentang sumber daya tertentu: satu pengguna (bukan /usersrute, tetapi /users/9, yaitu "Pengguna yang dikenal sebagai # 9"), sehingga perbandingan 'set hasil kosong' Anda tidak masuk akal. 404 berarti bahwa objek itu tidak ada.
Chris Pfohl
29
404 hanya menunjukkan bahwa sumber daya yang diminta (dalam hal ini nomor pengguna 9) tidak ditemukan. Itu tidak ada hubungannya dengan apakah kode aplikasi dipecat atau tidak, itu tidak ada hubungannya dengan apakah aplikasi backend merespons atau tidak. Sebuah server web adalah tentang pertanyaannya, tidak ada penyebutan terbalik dalam pertanyaan tersebut.
Chris Pfohl
29
Alasan dalam jawaban ini sangat salah.
Kurt Spindler
21
404: klien dapat berkomunikasi dengan server yang diberikan, tetapi server tidak dapat menemukan apa yang diminta. Secara harfiah bahwa: permintaan diterima, diformat dengan baik dan benar (permintaan buruk 400), dikonfirmasi atau publik (401 tidak sah / dilarang 403), tidak diperlukan pembayaran (diperlukan pembayaran 402), metode permintaan baik-baik saja (metode tidak diperbolehkan 405 ), permintaan terima dapat dipenuhi (tidak dapat diterima 406). 200 Ok harus digunakan ketika pengguna mendapatkan sumber daya. Kosong bukan sumber daya. Kisaran 400 untuk kesalahan klien 500 kisaran untuk kesalahan server Singkatnya: Alasan Anda tidak aktif.
Derk-Jan
62

Pada awalnya, saya pikir 204 akan masuk akal, tetapi setelah diskusi, saya percaya 404 adalah satu-satunya jawaban yang benar. Pertimbangkan data berikut:

Pengguna: John, Peter

METHOD  URL                      STATUS  RESPONSE
GET     /users                   200     [John, Peter]
GET     /users/john              200     John
GET     /users/kyle              404     Not found
GET     /users?name=kyle`        200     []
DELETE  /users/john              204     No Content

Beberapa latar belakang:

  1. pencarian mengembalikan array, hanya saja tidak ada kecocokan tetapi memiliki konten: array kosong .

  2. 404 tentu saja terkenal dengan url yang tidak didukung oleh server yang diminta, tetapi sumber daya yang hilang sebenarnya sama.
    Meskipun /users/:namedicocokkan dengan users/kyle, pengguna Kyle tidak tersedia sumber daya sehingga 404 masih berlaku. Ini bukan permintaan pencarian, ini adalah referensi langsung oleh url dinamis , jadi 404 itu.

Pokoknya, dua sen saya :)

Justus Romijn
sumber
9
Membuang berat badan saya di belakang gaya ini untuk REST API. Tidak ada klien yang harus meminta / users / kyle kecuali diberitahukan bahwa sumber daya akan ada melalui panggilan ke salah satu / pengguna atau / pengguna? Name = kyle
Gary Barker
@ GaryBarker Tapi karena itu adalah "input pengguna" dalam beberapa jenis, API masih harus menanganinya dengan benar. Meskipun Anda harus mencegah 404 di klien ANDA, Anda tidak dapat dijamin bahwa itu sebenarnya sudah diperiksa. Merancang API harus dilakukan tanpa mempertimbangkan implementasi yang tepat dari klien Anda, terutama dalam hal input pengguna yang diperiksa.
RicoBrassers
Ini adalah jawaban yang paling saya setujui. Contoh sempurna tentang bagaimana saya ingin API berfungsi. Komentar @ GaryBarker juga sempurna. Ini kesalahan ketika Anda mencari sesuatu dengan ID dan itu tidak ada. Anda harus tahu bahwa ID ada sebelum melakukan panggilan. Sebagian besar karena mendapatkan beberapa respons kosong 'berhasil' hanya menendang kesalahan lebih jauh, mungkin untuk beberapa 'tidak dapat membaca nama properti yang tidak terdefinisi' ketika melakukan user.name atau sesuatu.
Jamie Twells
Bagaimana dengan kombinasi keduanya. Dengan asumsi pengguna memiliki teman. / users / kyle / friends? name = fred. Kyle tidak ada, jadi apakah tanggapan ini menjadi 404? Atau apakah itu 200 karena kita tidak benar-benar peduli tentang kyle, kita hanya peduli mencari teman-temannya dengan nama fred?
JSextonn
IMO yang akan menghasilkan 404, karena ini adalah permintaan yang tidak valid: Kyle tidak ada, jadi mencari teman-temannya juga tidak mungkin.
Justus Romijn
23

Jika diharapkan sumber daya ada, tetapi mungkin kosong, saya berpendapat bahwa mungkin lebih mudah untuk mendapatkan 200 OK dengan representasi yang menunjukkan bahwa hal itu kosong.

Jadi saya lebih suka / hal mengembalikan 200 OK dengan {"Item": []} daripada 204 tanpa apa-apa, karena dengan cara ini koleksi dengan 0 item dapat diperlakukan sama seperti koleksi dengan satu atau lebih banyak item di dalamnya.

Saya baru saja meninggalkan 204 No Content untuk PUTs dan DELETEs, di mana mungkin memang benar ada representasi yang bermanfaat.

Jika / hal / 9 benar-benar tidak ada, 404 sesuai.

j0057
sumber
1
Sepertinya Anda lebih suka memprogram melawan API menggunakan formulir yang lebih abstrak yang disebut RPC. Daripada mengakses sumber daya dengan mengikuti kata kerja dengan cermat dan url berbasis sumber daya seperti customers/1/addressbook, cara RPC adalah memanggil titik akhir seperti GetCustomerAddressBookdan menerima data atau pada dasarnya nol dan tidak perlu terlalu khawatir tentang kompleksitas HTTP. Ada pro dan kontra untuk keduanya.
The Muffin Man
2
@ Man Muffin, saya tidak yakin bagaimana Anda bisa berpura-pura tahu apakah saya lebih suka REST atau RPC, atau mengapa itu relevan dengan diskusi tentang kode status mana yang harus dikembalikan ke permintaan GET HTTP.
j0057
Saya memiliki beberapa masalah caching yang mengerikan ketika menggunakan 204. Chrome akan memperlakukan permintaan dengan aneh dan tidak akan menampilkan apa pun di jaringan dan menyimpan hasil sebelumnya. Bahkan dengan semua header tanpa cache di dunia. Saya setuju dengan jawaban ini, 200 tampaknya menjadi yang terbaik dengan array / objek kosong yang diteruskan ke pengguna.
Jack
22

Dalam proyek sebelumnya, saya telah menggunakan 404. Jika tidak ada pengguna 9, maka objek tidak ditemukan. Oleh karena itu 404 Tidak Ditemukan sesuai.

Untuk objek ada, tetapi tidak ada data, 204 Tidak Ada Konten akan sesuai. Saya pikir dalam kasus Anda, objeknya tidak ada sekalipun.

Maks
sumber
14

Menurut posting w3 ,

200 OK

Permintaan telah berhasil. Informasi yang dikembalikan bersama respons bergantung pada metode yang digunakan dalam permintaan

202 Diterima

Permintaan telah diterima untuk diproses, tetapi pemrosesan belum selesai.

204 Tidak Ada Konten

Server telah memenuhi permintaan tetapi tidak perlu mengembalikan entitas-badan, dan mungkin ingin mengembalikan metainformation yang diperbarui.

400 permintaan Buruk

Permintaan tidak dapat dipahami oleh server karena sintaksis yang salah. Klien TIDAK HARUS mengulangi permintaan tanpa modifikasi

401 Tidak Resmi

Permintaan membutuhkan otentikasi pengguna. Responsnya HARUS menyertakan bidang tajuk WWW-Otentikasi

404 tidak ditemukan

Server belum menemukan sesuatu yang cocok dengan Permintaan-URI. Tidak ada indikasi yang diberikan apakah kondisinya sementara atau permanen

JustCode
sumber
Posting w3 adalah tentang kode status HTTP. HTTP tidak identik dengan REST. REST sebagian besar tetapi tidak selalu menggunakan HTTP sebagai protokol transport. 404 adalah kode kesalahan transportasi HTTP. Jika REST akan sama dengan HTTP, bukankah seharusnya itu disebut HTTP?
anneb
1
@anneb Seperti yang Anda katakan REST menggunakan HTTP, jadi jawaban ini benar-benar masuk akal. REST bukan HTTP, toh REST bukan protokol. REST tidak perlu sama (atau sama dengan HTTP) agar jawaban ini tidak masuk akal.
Koray Tugay
@ Koray Tugay: pencarian google juga menggunakan http, jadi menurut jawaban ini pencarian google harus menanggapi status http 404 jika tidak ada yang cocok dengan pencarian?
anneb
@anneb Apakah Pencarian Google Anda menyebutkan aplikasi RESTful? Saya rasa tidak .. Karena itu jawabannya adalah tidak. Mengarahkan kembali ke pertanyaan awal dan jawaban ini alih-alih jatuh ke lubang kelinci .. Jika suatu hari Google Penelusuran membuat API RESTful (atau mungkin sudah, saya tidak tahu) itu mungkin kembali 204 No Contentketika tidak menemukan hasil. Tidak 404, ini memiliki hasil untuk Anda, tetapi tidak memiliki konten ..
Koray Tugay
13

Untuk meringkas atau menyederhanakan,

2xx: Data opsional: URI yang terbentuk dengan baik: Kriteria bukan bagian dari URI: Jika kriteria tersebut opsional, dapat ditentukan dalam @RequestBody dan @RequestParam harus mengarah ke 2xx. Contoh: filter berdasarkan nama / status

4xx: Data yang diharapkan: URI yang tidak terbentuk dengan baik: Kriteria adalah bagian dari URI: Jika kriteria itu wajib yang hanya dapat ditentukan dalam @PathVariable, maka harus mengarah ke 4xx. Contoh: pencarian dengan id unik.

Jadi untuk situasi yang ditanyakan: "users / 9" akan menjadi 4xx (mungkin 404) Tetapi untuk "users? Name = superman" harus 2xx (mungkin 204)

Ashish Singh
sumber
12

Ada dua pertanyaan yang diajukan. Satu di judul dan satu di contoh. Saya pikir ini sebagian mengarah pada jumlah perselisihan tentang respon mana yang sesuai.

Judul pertanyaan menanyakan tentang data kosong. Data kosong masih berupa data tetapi tidak sama dengan tidak ada data. Jadi ini menyarankan meminta set hasil, yaitu daftar, mungkin dari/users . Jika daftar kosong itu masih daftar karena itu 204 (Tidak Ada Konten) yang paling tepat. Anda baru saja meminta daftar pengguna dan telah disediakan satu, kebetulan tidak memiliki konten.

Contoh yang diberikan bukannya bertanya tentang objek tertentu, pengguna /users/9,. Jika pengguna # 9 tidak ditemukan maka tidak ada objek pengguna yang dikembalikan. Anda meminta sumber daya tertentu (objek pengguna) dan tidak diberikan karena tidak ditemukan, jadi 404 sesuai.

Saya pikir cara untuk menyelesaikannya adalah jika Anda dapat menggunakan respons seperti yang Anda harapkan tanpa menambahkan pernyataan kondisional, kemudian gunakan 204 jika tidak gunakan 404.

Dalam contoh saya, saya dapat mengulangi daftar kosong tanpa memeriksa untuk melihat apakah ada konten, tapi saya tidak bisa menampilkan data objek pengguna pada objek nol tanpa merusak sesuatu atau menambahkan tanda centang untuk melihat apakah itu nol.

Anda tentu saja dapat mengembalikan objek menggunakan pola objek nol jika itu sesuai dengan kebutuhan Anda, tetapi itu adalah diskusi untuk utas lainnya.

Kotak biru
sumber
9

Setelah melihat pertanyaan, Anda tidak boleh menggunakan 404mengapa?

Berdasarkan RFC 7231 kode status yang benar adalah204

Dalam jawaban di atas saya perhatikan 1 kesalahpahaman kecil:

1.- sumber daya adalah: /users

2.- /users/8bukan sumber daya, ini adalah: sumber daya /usersdengan parameter rute8 , konsumen mungkin tidak dapat melihatnya dan tidak mengetahui perbedaannya, tetapi penerbit mengetahui dan harus mengetahui hal ini! ... jadi ia harus mengembalikan respons yang akurat bagi konsumen. Titik.

begitu:

Berdasarkan RFC: 404 tidak benar karena sumber dayanya /usersditemukan, tetapi logika yang dieksekusi menggunakan parameter 8tidak menemukan apa pun contentuntuk kembali sebagai respons, jadi jawaban yang benar adalah:204

Poin utama di sini adalah: 404bahkan sumber daya tidak ditemukan untuk memproses logika internal

204is a: Saya menemukan sumber daya, logikanya dieksekusi tetapi saya tidak menemukan data menggunakan kriteria Anda yang diberikan dalam parameter rute jadi saya tidak bisa mengembalikan apa pun kepada Anda. Maaf, verifikasi kriteria Anda dan hubungi saya lagi.

200: ok saya menemukan sumber daya, logika dieksekusi (bahkan ketika saya tidak dipaksa untuk mengembalikan apa pun) mengambil ini dan menggunakannya sesuka Anda.

205: (opsi terbaik dari respons GET) Saya menemukan sumber daya, logika dijalankan, saya memiliki beberapa konten untuk Anda, gunakan dengan baik, oh omong-omong jika Anda akan membagikan ini dalam tampilan, segarkan tampilan ke tampilkan itu.

Semoga ini bisa membantu.

rodfraga
sumber
8

Apa jawaban yang ada tidak dijabarkan adalah membuat perbedaan apakah Anda menggunakan parameter jalur atau parameter kueri.

  • Dalam hal parameter jalur, parameter adalah bagian dari jalur sumber daya. Dalam hal /users/9, responsnya harus 404karena sumber daya itu tidak ditemukan. /users/9adalah sumber daya, dan hasilnya adalah unary, atau kesalahan, itu tidak ada. Ini bukan monad.
  • Dalam hal parameter kueri, parameter tersebut bukan bagian dari jalur sumber daya. Dalam hal /users?id=9, responsnya harus 204karena sumber daya /usersditemukan tetapi tidak dapat mengembalikan data apa pun. Sumber daya /usersada dan hasilnya adalah n-ary, itu ada bahkan jika itu kosong. Jika idunik, ini adalah monad.

Apakah akan menggunakan parameter jalur atau parameter kueri tergantung pada use case. Saya lebih suka parameter jalur untuk argumen wajib, normatif, atau identifikasi dan parameter kueri untuk argumen opsional, non-normatif, atau atribut yang dikaitkan (seperti paging, lokal collation, dan sebagainya). Dalam REST API, saya akan menggunakan /users/9tidak /users?id=9terutama karena bersarang mungkin untuk mendapatkan "catatan anak" seperti /users/9/ssh-keys/0untuk mendapatkan kunci publik ssh pertama atau /users/9/address/2untuk mendapatkan alamat pos ketiga.

Saya lebih suka menggunakan 404. Inilah alasannya:

  • Panggilan untuk metode unary (1 hasil) dan n-ary (n hasil) tidak boleh bervariasi tanpa alasan yang baik. Saya suka memiliki kode respons yang sama jika memungkinkan. Jumlah hasil yang diharapkan tentu saja merupakan perbedaan, katakanlah, Anda mengharapkan tubuh menjadi objek (unary) atau array objek (n-ary).
  • Untuk n-ary, saya akan mengembalikan array, dan jika tidak ada hasil, saya tidak akan mengembalikan tidak ada set (tidak ada dokumen), saya akan mengembalikan set kosong (dokumen kosong, seperti array kosong di JSON atau elemen kosong di XML ). Artinya, itu masih 200 tetapi dengan nol catatan. Tidak ada alasan untuk menaruh informasi ini di kawat selain di tubuh.
  • 204seperti sebuah voidmetode. Saya tidak akan menggunakannya untuk GET, hanya untuk POST, PUT, dan DELETE. Saya membuat pengecualian jika GETpengidentifikasi adalah parameter kueri bukan parameter jalur.
  • Tidak menemukan catatan itu seperti NoSuchElementException, ArrayIndexOutOfBoundsExceptionatau sesuatu seperti itu, disebabkan oleh klien menggunakan id yang tidak ada, jadi, itu adalah kesalahan klien.
  • Dari perspektif kode, mendapatkan 204berarti cabang tambahan dalam kode yang dapat dihindari. Ini memperumit kode klien, dan dalam beberapa kasus juga memperumit kode server (tergantung pada apakah Anda menggunakan entitas / model monads atau entitas / model biasa; dan saya sangat menyarankan untuk menjauh dari entitas / model monads, itu dapat menyebabkan bug yang buruk di mana karena dari monad yang Anda pikir operasi berhasil dan mengembalikan 200 atau 204 ketika Anda seharusnya mengembalikan sesuatu yang lain).
  • Kode klien lebih mudah untuk ditulis dan dipahami jika 2xx berarti server melakukan apa yang diminta klien, dan 4xx berarti server tidak melakukan apa yang diminta klien dan itu adalah kesalahan klien. Tidak memberi klien catatan bahwa klien yang diminta oleh id adalah kesalahan klien, karena klien meminta id yang tidak ada.

Terakhir tetapi tidak kalah pentingnya: Konsistensi

  • GET /users/9
  • PUT /users/9 dan DELETE /users/9

PUT /users/9dan DELETE /users/9harus kembali 204jika pembaruan atau penghapusan berhasil. Jadi apa yang harus mereka kembalikan jika pengguna 9 tidak ada? Tidak masuk akal memiliki situasi yang sama disajikan sebagai kode status yang berbeda tergantung pada metode HTTP yang digunakan.

Selain itu, bukan normatif, tetapi alasan budaya: Jika 204digunakan untuk GET /users/9hal berikutnya yang akan terjadi dalam proyek adalah bahwa seseorang berpikir kembali 204itu baik untuk metode n-ary. Dan itu menyulitkan kode klien, karena alih-alih hanya memeriksa 2xxdan kemudian mendekodekan tubuh, klien sekarang harus secara khusus memeriksa 204dan dalam hal itu lewati mendekode tubuh. Bud apa yang dilakukan klien sebagai gantinya? Buat array kosong? Kalau begitu, mengapa tidak menggunakannya? Jika klien membuat array kosong, 204 adalah bentuk kompresi bodoh. Jika klien menggunakan nullsebagai gantinya, kaleng cacing yang sama sekali berbeda dibuka.

Christian Hujer
sumber
3

204 lebih tepat. Terutama ketika Anda memiliki sistem peringatan untuk memastikan situs web Anda aman, 404 dalam kasus ini akan menyebabkan kebingungan karena Anda tidak tahu bahwa 404 peringatan adalah kesalahan backend atau permintaan normal tetapi respons kosong.

刘武豪
sumber
Anda seharusnya tidak mengembalikan 404 jika Anda memiliki kesalahan backend.
appalling22
3

Saya akan mengatakan, tidak ada yang benar-benar tepat. Seperti yang telah dikatakan - misalnya oleh @anneb, saya juga berpikir bahwa bagian dari masalah muncul dari penggunaan kode respons HTTP untuk mengangkut status yang berkaitan dengan layanan RESTful. Apa pun yang dikatakan layanan REST tentang pemrosesannya sendiri harus diangkut melalui kode khusus REST.

1

Saya berpendapat bahwa, jika server HTTP menemukan layanan apa pun yang siap untuk menjawab permintaan yang dikirim, ia seharusnya tidak merespons dengan HTTP 404 - pada akhirnya, sesuatu ditemukan oleh server - kecuali jika diberitahukan secara eksplisit oleh layanan yang memproses permintaan.

Mari kita asumsikan sejenak URL berikut: http://example.com/service/return/test.

  • Kasus A adalah bahwa server “hanya mencari file pada sistem file“. Jika tidak ada,404 sudah benar. Hal yang sama berlaku, jika ia meminta beberapa jenis layanan untuk memberikan file ini dengan tepat dan layanan itu memberi tahu bahwa tidak ada nama itu yang ada.
  • Dalam kasus B, server tidak bekerja dengan file "nyata" tetapi sebenarnya permintaan diproses oleh beberapa layanan lain - misalnya semacam sistem templating. Di sini, server tidak dapat membuat klaim tentang keberadaan sumber daya karena ia tidak tahu apa-apa tentang itu (kecuali diberitahu oleh layanan yang menanganinya).

Tanpa respons dari layanan secara eksplisit yang memerlukan perilaku berbeda, server HTTP hanya dapat mengatakan 3 hal:

  • 503 jika layanan yang seharusnya menangani permintaan tidak berjalan atau merespons;
  • 200 jika tidak, server HTTP dapat benar-benar memenuhi permintaan - tidak peduli apa layanan akan katakan nanti;
  • 400atau 404untuk menunjukkan bahwa tidak ada layanan seperti itu (yang bertentangan dengan "ada tetapi offline") dan tidak ada lagi yang ditemukan.

2

Untuk kembali ke pertanyaan yang ada: Saya pikir pendekatan terbersih adalah dengan tidak menggunakan HTTP kode respons apa pun selain yang dikatakan sebelumnya. Jika layanan hadir dan merespons, kode HTTP harus 200. Respons harus berisi status layanan yang dikembalikan dalam tajuk terpisah - di sini, layanan dapat mengatakan

  • REST:EMPTYmisal jika diminta untuk mencari sth. dan penelitian itu kembali kosong;
  • REST:NOT FOUNDjika diminta khusus untuk sth. "Seperti ID" - baik nama file atau sumber daya dengan ID atau entri No. 24, dll. - dan sumber daya spesifik itu tidak ditemukan (biasanya, satu sumber daya khusus diminta dan tidak ditemukan);
  • REST:INVALID jika ada bagian dari permintaan yang dikirim tidak dikenali oleh layanan.

(perhatikan bahwa saya mengawali ini dengan "REST:" dengan sengaja untuk menandai fakta bahwa sementara ini mungkin memiliki nilai yang sama atau kata-kata seperti halnya kode respons HTTP, mereka sangat berbeda.)

3

Mari kita kembali ke URL di atas dan memeriksa case B di mana layanan menunjukkan ke server HTTP bahwa itu tidak menangani permintaan ini sendiri tetapi meneruskannya ke SERVICE. HTTP hanya melayani apa yang dikembalikan SERVICE, tidak tahu apa-apa tentang return/testbagian yang ditangani SERVICE. Jika layanan itu berjalan, HTTP harus kembali 200karena memang menemukan sesuatu untuk menangani permintaan.

Status dikembalikan oleh SERVICE(dan yang, seperti yang disebutkan di atas, ingin dilihat di header terpisah) tergantung pada tindakan apa yang sebenarnya diharapkan:

  • jika return/testmeminta sumber daya tertentu: jika ada, kembalikan dengan status REST:FOUND; jika sumber daya itu tidak ada, kembalilah REST:NOT FOUND; ini dapat diperpanjang untuk kembali REST:GONEjika kita tahu itu pernah ada dan tidak akan kembali, dan REST:MOVEDjika kita tahu itu sudah hollywood
  • jika return/testdianggap operasi pencarian atau seperti filter: jika set hasil kosong, kembalikan set kosong dalam jenis yang diminta dan status REST:EMPTY; satu set hasil dalam jenis yang diminta dan statusREST:SUCCESS
  • jika return/testbukan operasi yang dikenali oleh SERVICE: kembali REST:ERRORjika benar-benar salah (misalnya kesalahan ketik retrun/test), atau REST:NOT IMPLEMENTEDdalam kasus itu direncanakan untuk nanti.

4

Perbedaan ini jauh lebih bersih daripada mencampur dua hal yang berbeda. Ini juga akan membuat proses debug lebih mudah dan pemrosesan hanya sedikit lebih kompleks, jika sama sekali.

  • Jika HTTP 404 dikembalikan, server memberi tahu saya, "Saya tidak tahu apa yang Anda bicarakan". Sementara bagian REST dari permintaan saya mungkin baik-baik saja, saya mencari par'Mach di semua tempat yang salah.
  • Di sisi lain, HTTP 200 dan REST: ERR memberi tahu saya bahwa saya mendapatkan layanan tetapi melakukan sesuatu yang salah dalam permintaan saya ke layanan.
  • Dari HTTP 200 dan REST: KOSONG, saya tahu bahwa saya tidak melakukan kesalahan - server yang benar, server menemukan layanan, permintaan yang tepat ke layanan - tetapi hasil pencarian kosong.

Ringkasan

Masalah dan diskusi muncul dari fakta bahwa kode respons HTTP digunakan untuk menunjukkan status layanan yang hasilnya dilayani oleh HTTP, atau untuk menunjukkan sth. itu tidak dalam lingkup server HTTP itu sendiri. Karena perbedaan ini, pertanyaan tidak dapat dijawab dan semua pendapat tunduk pada banyak diskusi.

Keadaan permintaan diproses oleh layanan dan bukan server HTTP BENAR-BENAR TIDAK BISA (RFC 6919) diberikan oleh kode respons HTTP. Kode HTTP HARUS (RFC 2119) hanya berisi informasi yang dapat diberikan oleh server HTTP dari cakupannya sendiri: yaitu, apakah layanan ditemukan untuk memproses permintaan atau tidak.

Sebagai gantinya, cara yang berbeda HARUS digunakan untuk memberi tahu konsumen tentang keadaan permintaan ke layanan yang sebenarnya memproses permintaan tersebut. Proposal saya adalah melakukannya melalui tajuk tertentu. Idealnya, nama header dan isinya mengikuti standar yang memudahkan konsumen untuk bekerja dengan tanggapan tesis.

dariok
sumber
2

Menurut RFC7231 - halaman59 ( https://tools.ietf.org/html/rfc7231#page-59 ) definisi dari 404 kode respon adalah:

6.5.4. 404 Tidak Ditemukan Kode status 404 (Tidak Ditemukan) menunjukkan bahwa server asal tidak menemukan representasi saat ini untuk sumber daya target atau tidak mau mengungkapkan bahwa ada. Kode status 404 tidak menunjukkan apakah kekurangan representasi ini bersifat sementara atau permanen; kode status 410 (Hilang) lebih disukai daripada 404 jika server asal tahu, mungkin melalui beberapa cara yang dapat dikonfigurasi, bahwa kondisi tersebut cenderung permanen. Respons 404 dapat disimpan dalam cache secara default; yaitu, kecuali dinyatakan sebaliknya oleh definisi metode atau kontrol cache eksplisit (lihat Bagian 4.2.2 dari [RFC7234]).

Dan hal utama yang menimbulkan keraguan adalah definisi sumber daya dalam konteks di atas. Menurut RFC yang sama (7231) definisi sumber daya adalah:

Sumber: Target permintaan HTTP disebut "sumber". HTTP tidak membatasi sifat sumber daya; itu hanya mendefinisikan antarmuka yang dapat digunakan untuk berinteraksi dengan sumber daya. Setiap sumber diidentifikasi oleh Uniform Resource Identifier (URI), seperti yang dijelaskan dalam Bagian 2.7 dari [RFC7230]. Ketika klien membuat pesan permintaan HTTP / 1.1, ia mengirimkan target URI dalam salah satu dari berbagai bentuk, sebagaimana didefinisikan dalam (Bagian 5.3 dari [RFC7230]). Ketika permintaan diterima, server merekonstruksi URI permintaan yang efektif untuk sumber daya target (Bagian 5.5 dari [RFC7230]). Salah satu tujuan desain HTTP adalah untuk memisahkan identifikasi sumber daya dari semantik permintaan, yang dimungkinkan dengan memasukkan semantik permintaan dalam metode permintaan (Bagian 4) dan beberapa bidang tajuk pengubah permintaan (Bagian 5).

Jadi dalam pemahaman saya kode status 404 tidak boleh digunakan pada permintaan GET yang berhasil dengan hasil kosong. (Contoh: daftar tanpa hasil untuk filter tertentu)

Filipe Moisés
sumber
2

Hal-hal seperti itu bisa subjektif dan ada beberapa argumen yang menarik dan beragam di kedua sisi. Namun [menurut saya] mengembalikan 404 untuk data yang hilang tidak benar . Berikut ini deskripsi yang disederhanakan untuk memperjelas ini:

  • Permintaan: Bisakah saya memiliki beberapa data?
  • Sumberdaya (API endpoint): Saya akan mendapatkan permintaan itu untuk Anda, di sini [mengirim respons data potensial]

Tidak ada yang rusak, titik akhir ditemukan, dan tabel dan kolom ditemukan sehingga DB ditanya dan data "berhasil" dikembalikan!

Sekarang - apakah "respons berhasil" itu memiliki data atau tidak, Anda meminta respons terhadap data "potensial" dan respons dengan data "potensial" terpenuhi. Tidak ada, kosong dll adalah data yang valid.

200 berarti permintaan apa pun yang kami lakukan berhasil. Saya meminta data, tidak ada yang salah dengan HTTP / REST, dan karena data (meskipun kosong) dikembalikan, "permintaan data" saya berhasil.

Kembalikan 200 dan biarkan pemohon berurusan dengan data kosong karena setiap skenario tertentu menjaminnya!

Pertimbangkan contoh ini:

  • Permintaan: Tabel "pelanggaran" kueri dengan ID pengguna 1234
  • Sumberdaya (API endpoint): Mengembalikan respons tetapi data kosong

Data ini menjadi kosong sepenuhnya valid. Ini berarti bahwa pengguna tidak memiliki pelanggaran. Ini adalah 200 karena semuanya valid, seperti yang dapat saya lakukan:

Anda tidak memiliki pelanggaran, makan muffin blueberry!

Jika Anda menganggap ini sebagai 404, apa yang Anda katakan? Pelanggaran pengguna tidak dapat ditemukan? Sekarang, secara tata bahasa itu benar, tapi itu tidak benar di dunia REST jika keberhasilan atau kegagalan adalah tentang permintaan. Data "pelanggaran" untuk pengguna ini dapat ditemukan dengan sukses, ada nol pelanggaran - bilangan real yang mewakili keadaan yang valid.


[Catatan nakal ..]

Dalam judul Anda, secara tidak sadar Anda setuju bahwa 200 adalah respons yang benar:

Apa kode respons REST yang tepat untuk permintaan yang valid selain data yang kosong?


Berikut adalah beberapa hal yang perlu dipertimbangkan ketika memilih kode status mana yang akan digunakan, terlepas dari subjektivitas dan pilihan rumit:

  1. Konsistensi . Jika Anda menggunakan 404 untuk "tidak ada data", gunakan setiap kali respons tidak mengembalikan data.
  2. Jangan menggunakan status yang sama untuk lebih dari satu makna . Jika Anda mengembalikan 404 saat sumber daya tidak ditemukan (mis. Titik akhir API tidak ada dll.) Maka jangan gunakan itu tanpa data yang dikembalikan. Ini hanya membuat berurusan dengan respons itu menyakitkan.
  3. Pertimbangkan konteksnya dengan cermat . Apa itu "permintaan"? Apa yang Anda katakan ingin Anda capai?
James
sumber
1

Menyandikan konten respons dengan enum umum yang memungkinkan klien untuk mengaktifkannya dan garpu logika sesuai. Saya tidak yakin bagaimana klien Anda akan membedakan perbedaan antara "data tidak ditemukan" 404 dan "sumber daya web tidak ditemukan" 404? Anda tidak ingin seseorang menjelajah ke pengguna Z / 9 dan meminta klien bertanya-tanya seolah-olah permintaan itu valid tetapi tidak ada data yang dikembalikan.

Silahkan masuk
sumber
1

Mengapa tidak menggunakan 410? Ini menunjukkan sumber daya yang diminta tidak ada lagi dan klien diharapkan tidak pernah membuat permintaan untuk sumber daya itu, dalam kasus Anda users/9.

Anda dapat menemukan rincian lebih lanjut tentang 410 di sini: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

Akshat
sumber
2
'klien diharapkan untuk tidak pernah membuat permintaan' - dan bagaimana jika pengguna itu dibuat nanti, jawaban Anda menyarankan Anda dapat menjamin bahwa pengguna ini tidak akan pernah ada, itu adalah asumsi yang sangat berani dan kemungkinan salah
Holly
Apa yang dikatakan Holly. Untuk menambah poinnya: Sekalipun pengguna ada dan terhapus, 410 salah, karena bagaimana jika pengguna dibatalkan penghapusan? (Jenis kasus khusus mana yang akan dibuat nanti.)
Christian Hujer
karena 410 seharusnya menjadi situasi permanen. restapitutorial.com/httpstatuscodes.html
Akostha
1

Sangat menyedihkan bahwa sesuatu yang begitu sederhana dan didefinisikan dengan baik menjadi "berbasis opini" di utas ini.

Server HTTP hanya mengetahui "entitas", yang merupakan abstraksi untuk konten apa pun, baik itu halaman web statis, daftar hasil pencarian, daftar entitas lain, deskripsi json tentang sesuatu, file media, dll.

Setiap entitas tersebut diharapkan dapat diidentifikasi oleh URL yang unik, misalnya

  • / user / 9 - entitas tunggal: ID USER = 9
  • / pengguna - satu entitas: DAFTAR semua pengguna
  • /media/x.mp3 - entitas tunggal: FILE media yang disebut x.mp3
  • / search - sebuah entitas tunggal: KONTEN dinamis berdasarkan params kueri

Jika server menemukan sumber daya dengan URL yang diberikan, tidak peduli apa isinya - 2G data, null, {}, [] - selama ada, itu akan menjadi 200. Tetapi jika entitas tersebut adalah tidak dikenal ke server, DIHARAPKAN untuk mengembalikan 404 "Tidak Ditemukan".

Satu kebingungan tampaknya berasal dari pengembang yang berpikir jika aplikasi memiliki penangan untuk bentuk jalur tertentu, seharusnya tidak menjadi kesalahan. Di mata protokol HTTP, tidak masalah apa yang terjadi di internal server (mis. Apakah router default merespons atau handler untuk bentuk lintasan tertentu), selama tidak ada entitas yang cocok pada server ke server. URL yang diminta (yang meminta file MP3, halaman web, objek pengguna dll), yang akan mengembalikan konten yang valid (kosong atau sebaliknya), itu harus 404 (atau 410 dll).

Titik kebingungan lainnya tampaknya berada di sekitar "tidak ada data" dan "tidak ada entitas". Yang pertama adalah tentang konten suatu entitas, dan yang terakhir tentang keberadaannya.

Contoh 1:

  • Tidak ada data: / pengguna mengembalikan 200 OK, tubuh: [] karena belum ada yang terdaftar
  • Tidak ada entitas: / pengguna mengembalikan 404 karena tidak ada jalur / pengguna

Contoh 2:

  • Tidak ada data: / user / 9 menghasilkan pengembalian 200 OK, tubuh: {}, karena ID pengguna = 9 tidak pernah memasukkan data pribadinya
  • Tidak ada entitas: / user / 9 mengembalikan 404 karena tidak ada ID pengguna = 9

Contoh 3:

  • Tidak ada data: / search? Name = Joe mengembalikan 200 OK [], karena tidak ada Joe di DB
  • Tidak ada entitas: / search? Name = Joe mengembalikan 404 karena tidak ada jalur / pencarian
Darko Maksimovic
sumber
0

404 akan sangat membingungkan bagi klien mana pun jika Anda kembali hanya karena tidak ada data sebagai respons.

Bagi saya, Kode Respon 200 dengan tubuh kosong sudah cukup untuk memahami bahwa semuanya sempurna tetapi tidak ada data yang cocok dengan persyaratan.

lebih gelap
sumber
0

Menurut Microsoft: Controller mengembalikan tipe di ASP.NET Core web API , gulir ke bawah hampir ke bawah, Anda menemukan uraian berikut tentang 404 yang berkaitan dengan objek yang tidak ditemukan dalam database. Di sini mereka menyarankan bahwa 404 sesuai untuk Data Kosong.

masukkan deskripsi gambar di sini

Bill Roberts
sumber
0

Seperti yang dinyatakan oleh banyak orang, 404 menyesatkan dan tidak memungkinkan klien untuk melakukan diskriminasi jika permintaan uri tidak ada, atau jika uri yang diminta tidak dapat mengambil sumber daya yang diminta.

Status 200 diharapkan berisi data sumber daya - jadi itu bukan pilihan yang tepat. Status 204 berarti sesuatu yang lain sepenuhnya dan tidak boleh digunakan sebagai respons untuk permintaan GET.

Semua status lain yang ada tidak berlaku, karena satu dan lain hal.

Saya telah melihat topik ini dibahas berulang-ulang di banyak tempat. Bagi saya, sangat jelas bahwa untuk menghilangkan kebingungan seputar topik, diperlukan status kesuksesan yang berdedikasi. Sesuatu seperti " 209 - Tidak ada sumber daya untuk ditampilkan".

Ini akan menjadi status 2xx karena tidak menemukan ID tidak boleh dianggap sebagai kesalahan klien (jika klien tahu semua yang ada di DB server, mereka tidak perlu meminta apa pun ke server, bukan?). Status khusus ini akan mengatasi semua masalah yang diperdebatkan dengan menggunakan status lain.

Satu-satunya pertanyaan adalah: bagaimana saya membuat RFC menerima ini sebagai standar?

Umberto Bar
sumber