Bagaimana cara memilih kode status HTTP di REST API untuk "Belum Siap, Coba Lagi Nanti"? [Tutup]

152

Saya sedang mengembangkan API TENANG di mana http://server/thingyapi/thingyblob/1234mengembalikan file (alias "gumpalan") yang terkait dengan thingy # 1234 untuk diunduh. Tetapi mungkin permintaan tersebut dibuat pada suatu waktu file tidak ada di server tetapi yang paling pasti akan tersedia di lain waktu. Ada proses batch di server yang menghasilkan semua gumpalan untuk semua barang. Thingy 1234 sudah ada dan datanya, selain gumpalan, sudah tersedia. Server belum dapat membuat gumpalan benda 1234 belum.

Saya tidak ingin mengembalikan 404; itu untuk barang yang tidak ada. Ini adalah benda yang ada, tetapi gumpalannya belum dihasilkan. Agak seperti video YouTube yang "sedang diproses". Saya juga tidak berpikir kode pengalihan tidak tepat; tidak ada URL "lain" untuk dicoba.

Apa kode status HTTP yang benar untuk dikembalikan dalam kasus seperti itu?

JCCyC
sumber
3
Agak terkait
Rob Hruska
7
Pertama, jika thingy 1234 belum memiliki representasi yang dapat GET, dalam arti apa itu ada sebagai sumber daya (dari perspektif klien)? Fakta bahwa, internal ke server ada pekerjaan yang antri untuk membuat 1234, tampaknya tidak menyiratkan bahwa sumber daya 1234 ada. Kedua, dari mana klien mendapatkan URI ... / thingyblob / 1234? Server mungkin seharusnya tidak menyediakan URI itu kepada klien sampai sumber dayanya benar-benar GET.
Andy Dennie
1
Suatu benda memiliki sifat-sifat lain yang berharga selain dari gumpalan. Hanya gumpalan yang membutuhkan waktu untuk menghasilkan. Klien mendapatkan mereka dengan, misalnya, server / thingyapi / thingy / 1234
JCCyC
10
Standar HTTP memberikan panduan tentang kode status mana yang digunakan untuk situasi apa. Oleh karena itu pertanyaan ini sebenarnya tidak didasarkan pada pendapat .
Raedwald
2
Bagaimana dengan 204"Tidak Ada Konten"? Apakah menunjukkan bahwa server telah berhasil memproses permintaan dan tidak mengembalikan konten [saat ini].
Timo

Jawaban:

77

Saya sarankan 202 - Accepted. Dari dokumentasi :

Permintaan telah diterima untuk diproses, tetapi pemrosesan belum selesai. [...] Tujuannya adalah untuk memungkinkan server menerima permintaan untuk beberapa proses lain (mungkin proses berorientasi batch yang hanya dijalankan sekali per hari)

matsev
sumber
62
-1: Ini masuk akal untuk permintaan yang memulai proses yang akhirnya menciptakan "thingy # 1234", tetapi tidak untuk permintaan GET yang dikeluarkan setelahnya untuk "thingy # 1234" itu sendiri. Secara khusus, 202 menyarankan bahwa sebagai hasil dari permintaan GET, layanan akan mengirimkan data untuk "thingy # 1234" di kemudian hari. Ini sama sekali tidak benar.
Sam Harwell
7
Ia juga mengatakan: "Entitas yang dikembalikan dengan respons ini HARUS menyertakan indikasi status permintaan saat ini dan apakah pointer ke monitor status atau perkiraan kapan pengguna dapat mengharapkan permintaan terpenuhi.", Jadi ini akan menjadi cara yang baik untuk memberi tahu klien bahwa gumpalan belum siap, dan cara untuk mengetahui kapan gumpalan siap.
Remy Lebeau
3
Saya berpendapat bahwa "diterima untuk diproses" menunjukkan bahwa Anda menyimpan permintaan untuk ditindaklanjuti nanti. Jika diabaikan, Anda harus mengembalikan kode 4xx atau 5xx untuk menunjukkan kepada klien bahwa mereka mungkin ingin mencoba lagi.
Lukas
3
102 (pemrosesan) tampaknya juga pilihan yang masuk akal kadang-kadang meskipun itu dalam spesifikasi webdav.
akostadinov
2
Tidak bisa tidak setuju dengan jawaban ini. Server tidak mengembalikan apa pun, atau berencana untuk (tidak melakukan pemrosesan apa pun karena permintaan ini - yang seharusnya tidak untuk GET). Dengan demikian, sumber daya dalam beberapa cara tidak tersedia untuk klien. Ini harus diperlakukan sebagai kesalahan sehingga tidak ada kode 2XX yang sesuai. Sesuatu di ruang 4XX atau 5XX. Permintaan belum "diterima untuk diproses" , permintaan tersebut pada praktiknya sedang dibuang
Adam
52

"Masalah", seperti apa adanya, ada di sisi server: klien telah membuat permintaan yang bagus, tetapi server tidak dapat memenuhinya. Jadi saya cenderung ke "Server Error", kode status 5xx.

Quoth RFC 7231 (standar HTTP saat ini, penekanan ditambahkan):

Kelas 5xx (Kesalahan Server) kode status menunjukkan bahwa server sadar bahwa ia telah melakukan kesalahan atau tidak mampu melakukan metode yang diminta . Kecuali ketika menanggapi permintaan HEAD, server HARUS mengirim representasi yang berisi penjelasan tentang situasi kesalahan, dan apakah itu kondisi sementara atau permanen.

Catatan

  • "salah atau tidak mampu melakukan permintaan": terlepas dari judul "Kesalahan Server", mereka bukan hanya untuk kesalahan server.
  • " sementara atau permanen": kode-kode ini cocok untuk sumber daya yang sementara tidak tersedia, seperti milik Anda.

Dari kode yang tersedia, saya akan mengatakan 503, "Layanan Tidak Tersedia" adalah yang paling cocok:

Kode status 503 (Layanan Tidak Tersedia) menunjukkan bahwa server saat ini tidak dapat menangani permintaan karena kelebihan sementara atau pemeliharaan terjadwal, yang kemungkinan akan dikurangi setelah beberapa penundaan. Server MUNGKIN mengirimkan bidang Coba Lagi-Setelah header ... untuk menyarankan jumlah waktu yang sesuai bagi klien untuk menunggu sebelum mencoba kembali permintaan.

catatan:

  • "kemungkinan akan dikurangi setelah beberapa penundaan": berlaku untuk kasus Anda.
  • "temporary overload": tidak berlaku untuk kasus Anda. Tapi, bisa diperdebatkan, apakah server Anda jauh lebih cepat, pemrosesan batch akan sudah dilakukan ketika klien mengajukan permintaan, sehingga merupakan semacam "overload": klien meminta sumber daya lebih cepat dari server dapat membuat mereka tersedia.
  • Coba lagi cocok untuk layanan Anda, jadi balasan Anda harus menyertakan a Retry-After nilai. Anda bisa memberikan nilai perkiraan waktu penyelesaian untuk eksekusi selanjutnya dari proses batch, atau interval eksekusi dari proses batch.

Namun, mendefinisikan kode status 5xx Anda sendiri (591) diizinkan , akan memiliki semantik yang salah:

klien HARUS memahami kelas kode status apa pun, seperti yang ditunjukkan oleh digit pertama, dan memperlakukan kode status yang tidak dikenali sebagai setara dengan kode status x00 kelas itu

Klien akan memperlakukan kode status Anda sendiri sebagai 500, "Kesalahan Server Internal" , yang tidak benar.

Raedwald
sumber
2
Saya gagal melihat bagaimana ini lebih baik daripada 202: benramsey.com/blog/2008/04/…
JCCyC
4
@JCCyC, blog Anda memiliki alasan yang bagus untuk mengembalikan 202 sebagai tanggapan atas permintaan untuk membuat sesuatu (POST atau PUT). Pertanyaannya tampaknya bertanya tentang apa yang harus dikembalikan untuk GET.
Raedwald
@ JCCyC itu bisa dilihat sebagai warna berbeda dari ketidak-siap-an: bayangkan ajax untuk sumber daya itu, apakah Anda lebih suka 202 sebagai status sukses atau 503 sebagai status kesalahan? sehingga Anda dapat melihat makna mana yang Anda sukai secara implisit dalam konteks reaksi aplikasi Anda terhadap respons
rloth
Saya juga menyukai aspek praktis "Retry-After" yang cocok dengan sesuatu yang "tidak siap"
rloth
1
NB: "Retry-After" juga dapat digunakan dengan 307 - TEMPORARY REDIRECTyang baik jika Anda ingin memaksa sisi klien untuk menunggu di tempat lain sementara sumber daya Anda sedang "disiapkan"
rloth
28

Saya pikir 423 - Terkunci dapat digunakan untuk tujuan ini:

Kode status 423 (Terkunci) berarti sumber atau tujuan sumber daya metode dikunci. Respons ini HARUS berisi kode prekondisi atau pascakondisi yang tepat, seperti 'kunci-diserahkan-diserahkan' atau 'tidak-bertentangan-kunci'.

Fernando Ortega
sumber
1
Jawaban yang sangat bagus! Saya bertanya-tanya mengapa itu tidak memiliki lebih banyak upvotes.
lex82
10
Mungkin karena itu adalah kode HTTP WebDAV?
Stephan L
1
Dari akka-http ada StatusCode RetryWith = reg (c (449) ("Coba Lagi", "Permintaan harus dicoba lagi setelah melakukan tindakan yang sesuai.")) Di mana tindakan akan menunggu dan coba lagi
ozma
2
Dalam banyak hal saya setuju dengan ini. Saya memiliki situasi yang serupa (dalam kasus saya mencari dari indeks yang mungkin belum diisi). Secara semantik, saya pikir ini benar. Namun, RFC untuk 423 menyatakan "Respons ini HARUS mengandung kode prekondisi atau pascakondisi yang tepat, seperti 'kunci-diserahkan-diserahkan' atau 'tanpa-konflik-kunci'." Tidak yakin bagaimana menerapkannya di sini. Dan secara pribadi saya akan pergi dengan 409 Konflik, tetapi itu telah diturunkan tanpa komentar - tidak yakin mengapa?
Adam
22

Saya tidak ingin mengembalikan 404; itu untuk barang yang tidak ada.

URL tidak sesuai dengan permintaan sesuatu.

http://server/thingyapi/thingyblob/1234

Klien meminta thingyblob, yang tidak ada. Jika ada, Anda akan memberikannya kepada mereka.

404.

funroll
sumber
1
Saya senang seseorang mengatakan ini! Saya tidak percaya ada begitu banyak orang yang menganggapnya 503sebagai respons yang tepat. Belum lagi beberapa saran aneh lainnya.
Jason Desrosiers
Meskipun saya setuju bahwa 404 adalah respons yang paling tepat di sini, itu tidak menjawab pertanyaan OP bagaimana menunjukkan kapan thingy tersedia :-). Saya pikir bidang Coba Lagi Setelah tampaknya kandidat terbaik tetapi hanya secara resmi dapat digunakan untuk kode 503 dan 3xx. @Jason: Saya pikir itu menjelaskan beberapa saran aneh.
Ron Deijkers
Saya pikir ini adalah jawaban terbaik. Anda diizinkan mengembalikan tubuh dalam respons 404. Tubuh dapat menunjukkan bahwa benda itu akan tersedia di kemudian hari. Atau gunakan Retry-After header juga. Standar perlu direntangkan sedikit di sini karena tidak menutupi kasus ini dengan baik.
WW.
4
Orang-orang menjadi terlalu terbiasa dengan 404 halaman makna yang tidak menemukan bahwa mereka tidak dapat secara logis memisahkannya ketika dalam konteks API.
The Muffin Man
1
Ini sooooo 404. Thingyblob belum ada, atau pernah .. Untuk http itu tidak relevan jika akan pernah tersedia. Saat ini tidak ada, dan 404-nya. Ketika akan tersedia adalah masalah lain, yang dapat diselesaikan dengan mendorong pesan dari server ke klien sayin thingyblob: 1234 tersedia. Lakukan mendapatkan lagi dan voila ..
100r
21

Pilihan lain: 503 - Service Unavailable.

Brian Kelly
sumber
5
Menurut W3C itu bukan apa yang ingin Anda katakan kepada klien (walaupun itu berarti "datang lagi" dengan beberapa cara): "Server saat ini tidak dapat menangani permintaan karena kelebihan sementara atau pemeliharaan server. Implikasinya adalah bahwa ini adalah kondisi sementara yang akan dikurangi setelah beberapa penundaan. Jika diketahui, panjang penundaan MUNGKIN ditunjukkan dalam tajuk Coba-Setelah. Jika tidak Coba lagi-Setelah diberikan, klien HARUS menangani respons seperti halnya untuk 500 tanggapan. "
skalee
4
Layanan tidak tersedia, layanan tersedia tetapi pemrosesan tidak lengkap. Jadi 503 mungkin bukan ide yang bagus.
Ishtiaque Khan
17

Karena sumber daya Anda belum siap, Anda mungkin tahu kapan (kurang-lebih) itu akan tersedia dan kapan klien dapat mencoba kembali permintaannya. Ini berarti Anda mungkin ingin memanfaatkan Retry-After header . Header ini valid dengan 503 (Layanan Tidak Tersedia), yang berarti seluruh situs tidak aktif untuk pemeliharaan, dan respons 3xx (Pengalihan).

Menurut pendapat saya 302 (Ditemukan) dengan Retry-After header akan menjadi pilihan terbaik, tetapi saya tidak yakin apakah bidang Lokasi header respons dapat sama dengan permintaan url. Itu redirect melingkar.

skalee
sumber
3
Bahkan jika diizinkan, jika klien belum menerapkan dukungan untuk tajuk Coba-Setelah maka Pengalihan 3xx ke halaman yang sama akhirnya akan berakhir pada 503 ... (opsional dengan tajuk Coba Lagi-Setelah tentu saja)
Ron Deijkers
1
Retry-After juga berlaku dengan HTTP 429 "Too Many Requests", ditambahkan oleh RFC 6585 (April 2012). Ini mungkin tepat jika alasan untuk sumber daya belum siap adalah klien telah memberikan server terlalu banyak pekerjaan yang harus dilakukan.
Silas S. Brown
8

409 Konflik

Menunjukkan bahwa permintaan tidak dapat diproses karena konflik dalam permintaan, seperti konflik edit dalam kasus beberapa pembaruan. [Sumber Wikipedia.]

Ini bisa tepat.

Jika Anda tidak dapat memenuhi permintaan dengan mengembalikan data - maka itu tidak berhasil. Saya pikir 202 menyarankan server telah mengantri permintaan dan itu akan memenuhi permintaan nanti. Tetapi dalam kasus Anda, permintaan adalah untuk data sekarang dan telah gagal. Jika Anda mencoba lagi nanti itu adalah permintaan yang berbeda.

Saya pikir Anda memiliki konflik .. Anda ingin data .. tetapi sedang diedit / diperbarui. Ini juga akan menjadi kasus jika Thingy1234 sudah ada dan telah berhasil diunduh sebelumnya, tetapi sekarang sedang dalam proses diedit tidak tersedia sementara pengeditan sedang berlangsung.

J Moore
sumber
2
Tidak yakin mengapa ini ditolak. Sepertinya jawaban yang tepat untuk saya. Dari RFC: "Kode status 409 (Konflik) menunjukkan bahwa permintaan tidak dapat diselesaikan karena konflik dengan keadaan saat ini dari sumber daya target. Kode ini digunakan dalam situasi di mana pengguna mungkin dapat menyelesaikan konflik dan kirim ulang permintaan. "Anda meminta sumber daya yang tidak dapat dikembalikan oleh server karena server sedang dalam proses memperbarui sumber daya itu - yaitu karena kondisi sumber daya saat ini. Klien dapat menyelesaikan ini dengan menunggu dan mengirim ulang
Adam
1
@ Adam Saya pikir implikasi dalam "pengguna mungkin dapat menyelesaikan konflik" adalah bahwa sesuatu tentang pengiriman ulang akan berbeda, selain hanya menunggu.
Pengembang Holistik
3

501 - Tidak Diimplementasikan

Persis seperti bagaimana bunyinya. Fitur yang belum diterapkan, tetapi menyiratkan ketersediaan di masa depan.

Berikut ini tautan ke ringkasan kesalahan 5xx .

Dan
sumber
4
Untuk pertanyaan ini, sepertinya fitur itu sendiri ada, tetapi item yang diminta tidak.
Lukas
Deskripsi Lukas 501 dari tautan dalam jawaban saya, '... tidak memiliki kemampuan untuk memenuhi permintaan. Biasanya ini menyiratkan ketersediaan di masa depan '. Ini memenuhi persis apa yang diminta OP. Terlepas dari apakah data ada di server atau DB-nya. Hasil akhirnya adalah bahwa itu tidak dapat diakses melalui API untuk saat ini. Karenanya API tidak dapat memenuhi permintaan, tetapi ingin menyatakan bahwa itu akan tersedia di masa depan melalui kode http.
Dan