Saya bekerja dengan REST API yang berada di server yang menangani data untuk banyak perangkat IoT.
Tugas saya adalah meminta server menggunakan API untuk mengumpulkan informasi kinerja spesifik tentang perangkat tersebut.
Dalam satu contoh, saya mendapatkan daftar perangkat yang tersedia dan pengidentifikasi yang sesuai, kemudian meminta server untuk detail lebih lanjut menggunakan pengidentifikasi tersebut (GUID).
Server mengembalikan 500 Internal Server Error
permintaan untuk salah satu ID tersebut. Dalam aplikasi saya, pengecualian dilemparkan dan saya tidak melihat detail tentang kesalahan tersebut. Jika saya memeriksa respons lebih dekat dengan Postman , saya dapat melihat bahwa server mengembalikan JSON di dalam tubuh yang berisi:
errorMessage: "This ID does not exist"
.
Abaikan fakta bahwa server memberikan ID untuk memulai - itu masalah tersendiri bagi pengembang.
Haruskah REST API mengembalikan a 500 Internal Server Error
untuk melaporkan bahwa kueri merujuk objek yang tidak ada? Menurut pendapat saya, kode respons HTTP harus merujuk secara ketat ke status panggilan REST, alih-alih ke mekanisme internal API. Saya harapkan 200 OK
jawaban dengan yang berisi kesalahan dan deskripsi, yang akan menjadi hak milik API yang bersangkutan.
Terjadi pada saya bahwa ada perbedaan potensial dalam harapan tergantung pada bagaimana panggilan REST terstruktur.
Pertimbangkan contoh-contoh ini:
http://example.com/restapi/deviceinfo?id=123
http://example.com/restapi/device/123/info
Dalam kasus pertama, ID perangkat dilewatkan sebagai variabel GET. A 404 atau 500 akan menunjukkan bahwa path ( /restapi/deviceinfo
) tidak ditemukan atau mengakibatkan kesalahan server.
Dalam kasus kedua, ID perangkat adalah bagian dari URL. Saya akan lebih memahami tentang 404 Not Found
, tetapi masih bisa berdebat berdasarkan bagian mana dari jalur ditafsirkan sebagai variabel versus titik akhir.
sumber
Jawaban:
Saya pikir respons 404 adalah kecocokan semantik terbaik di sini, karena sumber daya yang Anda coba temukan (seperti diwakili oleh URI yang digunakan untuk kueri) tidak ditemukan. Mengembalikan muatan kesalahan dalam tubuh adalah wajar, tetapi tidak diperlukan.
Menurut RFC 2616 , definisi kode status 404 adalah:
sumber
/questions
, itu/questions/368213
. Titik akhir itu tidak ada dalam skenario Anda. Pikirkan seperti ini: jika Anda melakukan GET di / foo / bar dan tidak ada bar, mengapa responsnya berbeda jika / foo ada atau tidak?How do you differentiate between a 404 meaning "the query returned no results" and a 404 meaning "the endpoint does not exist"?
- 400 Permintaan Buruk.Saya akan menggunakan contoh Anda.
Jika titik akhir mengembalikan json array , pilihan terbaik adalah
200 OK
dengan array kosong jika tidak ada hasil yang ditemukan.Jika titik akhir dirancang untuk mengembalikan hasil tunggal , pilihan saya akan
404 NOT FOUND
, karena, bagi saya, sintaks yang tepat untuk jenis endpoint adalah:http://example.com/restapi/deviceinfo/123
. Saya biasanya menggunakan param permintaan hanya untuk memfilter dan ketika endpoint saya mengembalikan array.Saya pikir pertanyaan ini sudah dijawab di sini . POST atau DAPATKAN, pilihan yang lebih baik tampaknya
404 NOT FOUND
karena sumber daya123
tidak ditemukan.Dalam kedua kasus saya tidak bisa melihat keharusan untuk menjelaskan alasan permintaan tidak selesai. Informasi permintaan dan kode HTTP sudah menjelaskan alasannya.
sumber
/itms/1234
atau tidak/items/12234
.HTTP 404
benar, karena server memahami sumber daya apa yang diminta klien, tetapi tidak memiliki sumber daya itu.Fakta bahwa Anda bekerja dengan "REST API" adalah kuncinya. API harus berperilaku seperti sedang melakukan Transfer Negara Representasi, bukan menjalankan fungsi. (Tentu, istilah "REST" telah memiliki makna yang lebih luas, tetapi Anda masih dapat menggunakan makna literalnya untuk efek yang baik di sini.) Klien telah meminta status sumber daya yang dijelaskan oleh URL
http://example.com/restapi/device/123/info
. Querystring (/deviceinfo?id=123
) tidak akan mengubah situasi. Server tahu Anda meminta untuk mentransfer status perangkat 123, tetapi server tidak mengenali itu sebagai sumber daya yang dikenal. Oleh karena ituHTTP 404
.Kemungkinan tanggapan lain yang dibahas di sini memiliki makna khusus juga:
HTTP 200
- Kami punya negara untuk Anda; ada di tubuh respons.HTTP 204
- Kami punya negara untuk Anda; itu kosong.HTTP 400
- Kami tidak dapat memberi tahu sumber daya apa yang Anda tanyakan. Perbaiki URL Anda.HTTP 500
- Kami tidak berfungsi. Bukan kesalahanmu.Lihat RFC 2616 Sec. 10 sesuai kebutuhan.
sumber
Kesalahan 5xx biasanya digunakan untuk menunjukkan bahwa server mengalami kesalahan dan tidak dapat menyelesaikan permintaan. Jika server menerima permintaan, berhasil menguraikannya, dan kemudian berfungsi, itu seharusnya tidak mengembalikan kesalahan 5xx.
Saya tidak yakin apakah ada jenis konvensi tentang apa yang harus dikembalikan jika kueri tidak membuahkan hasil. Saya telah melihat apa yang Anda gambarkan (200 dengan badan yang berisi pesan) serta 404 yang menunjukkan bahwa hasilnya tidak ditemukan. 200 mungkin paling masuk akal - permintaan berhasil diselesaikan dan tidak ada masalah dengan permintaan klien atau selama server memproses permintaan. Badan dapat mengirimkan pesan ke klien.
Saya akan memperlakukan kedua contoh Anda (
http://example.com/restapi/deviceinfo?id=123
danhttp://example.com/restapi/device/123/info
) sama -123
parameternya adalah. Kedua kasus tersebut merupakan cara berbeda dalam menyusun permintaan untuk mendapatkan informasi perangkat untuk perangkat dengan ID 123.Pertama, saya akan mempertimbangkan otorisasi dan otentikasi. Jika pengguna tidak memiliki izin yang sesuai, saya akan mengembalikan 403 atau 401 yang sesuai. Meskipun disebut "Tidak Diotorisasi", pemahaman saya adalah bahwa 401 lebih tentang otentikasi dan 403 adalah tentang tidak sah atau izin ditolak. Saya tidak akan terlalu pilih-pilih di sini, jika Anda hanya ingin tetap menggunakan 403 untuk semua kesalahan autentikasi dan otorisasi.
Lalu, saya akan menangani ID. Berdasarkan contoh Anda, sepertinya itu adalah ID numerik. Jika nilai non-numerik diberikan, saya akan mengembalikan 400. Jika parameternya mungkin merupakan pengidentifikasi perangkat yang valid, maka saya akan melanjutkan pemrosesan. Jika ada argumen lain, mereka juga akan diperiksa di sini. Saya berharap badan respons berisi informasi yang sesuai tentang mengapa permintaan itu buruk.
Jika semua parameter valid, saya akan mulai memproses permintaan. Jika sistem atau ketergantungan apa pun (database, layanan pihak ketiga, layanan internal lain) tidak tersedia, saya akan mengembalikan kode 5xx - 503 akan lebih spesifik, tetapi 500 juga dapat diterima. Dalam kedua kasus itu, saya akan mengembalikan tubuh dengan detail tambahan. Pertimbangkan bahwa jika ketergantungan eksternal melaporkan Batas Waktu Permintaan 408, saya akan memakannya dan mengembalikan 500 kepada klien saya, memungkinkan klien untuk menerima 408 hanya jika permintaan ke sistem saya habis. Jika sistem dapat menyelesaikan permintaan, saya akan mengembalikan 200 dan badan yang sesuai.
204 mungkin berguna dalam beberapa kasus, tetapi menghalangi Anda mengirim badan tanggapan. Terutama dalam pengaturan API, mengirimkan badan respons dengan informasi yang dapat dimasukkan ke dalam mekanisme logging atau pelaporan sepertinya keputusan yang tepat untuk dibuat dalam banyak kasus.
Satu-satunya waktu 404 akan dikembalikan adalah jika server tidak memiliki
/deviceinfo
titik akhir atau/device/:id/info
titik akhir.Saya tidak akan mempertimbangkan ID yang tidak ditemukan sama dengan sumber daya yang tidak ditemukan. Sumber daya adalah informasi perangkat untuk perangkat tertentu (dalam contoh Anda). Mengembalikan 404 berarti sumber daya (informasi perangkat) tidak ada. A 200 dengan badan yang sesuai berarti bahwa sistem memang dapat memberikan informasi perangkat. Mungkin ada atau tidak ada perangkat dengan ID yang ditentukan.
sumber
device: 123; status: not found;
. Lalu saya tahu kueri bekerja, dan API memberi tahu saya informasi yang berguna.Kesalahan HTTP 500-seri menunjukkan kerusakan server. Terlepas dari
501 Not Implemented
dan505 HTTP Version Not Supported
, menggunakan kode kesalahan ini membawa implikasi bahwa mencoba kembali permintaan di lain waktu dapat berhasil (meskipun hanya503 Service Unavailable
secara eksplisit menyatakan ini). Idealnya, server tidak boleh menghasilkan salah satu dari kode ini, meskipun ketidakmampuan untuk menulis perangkat lunak bebas bug dan menyediakan server dengan sumber daya tak terbatas berarti Anda akan membutuhkannya dari waktu ke waktu.Untuk hasil "objek tidak ada", Anda mungkin harus mengembalikan
404 Not Found
(ketika permintaan untuk objek dengan nama), atau200 Success
dengan badan hasil yang kosong (saat mencari objek dengan atribut).204 No Content
terlihat menggoda, tapi saya akan menggunakannya hanya untuk situasi di mana kurangnya respon tubuh adalah hasil yang diharapkan.sumber
Sebagai klien API Anda, ketika saya melakukan salah satu dari panggilan ini:
http://example.com/restapi/deviceinfo?id=123
http://example.com/restapi/device/123/info
Saya berharap untuk mendapatkan kembali (representasi dari) suatu
DeviceInfo
objek (atau beberapa tipe tertentu, apakah itu tipe formal atau hanya sesuatu yang sesuai dengan konvensi "tipe bebek" yang terdokumentasi). Saya ingin200
status berarti saya benar-benar mendapatkannya, dan saya bisa terus menggunakannya.Untuk REST API, saya menganggap 400 dan 500 kode status sebagai sesuatu seperti pengecualian. Anda menggunakannya untuk menunjukkan kapan Anda tidak dapat mengembalikan respons "normal" untuk permintaan yang Anda terima, sehingga klien perlu melakukan sesuatu yang luar biasa daripada memproses informasi yang diharapkan akan diambil.
Ini berarti, sebagai konsumen API, bahwa saya dapat menggunakan semacam fungsi check-rest-rest yang mengambil respons atau melempar pengecualian. Itu keren; logika normal saya bisa berupa kode garis lurus, dan saya dapat mengatur penanganan kesalahan dengan cara yang sama dengan yang saya lakukan pada kode lokal. 404 tak terduga akan bermanifestasi sebagai pengecualian "tidak ada sumber daya" tanpa saya harus melakukan apa pun, bukan sebagai kesalahan "atribut hilang" ketika saya kemudian memproses
{ errorMessage: "Device 123 not found" }
seolah-olah itu adalahDeviceInfo
objek.Jika Anda alasan bahwa titik akhir
http://example.com/restapi/deviceinfo
yang ditemukan, dan itu hanyaid=123
yang tidak, dan begitu kembali 200 dengan pesan kesalahan di dalam tubuh, maka Anda sedang menciptakan jenis yang sama persis masalah antarmuka sebagai fungsi C yang bisa kembali baik perbaiki hasil atau kode kesalahan, atau metode yang mengindikasikan masalah dengan mengembalikan secara sewenang-wenangnull
. Adalah jauh lebih baik sebagai pengguna antarmuka Anda untuk memiliki kesalahan yang ditunjukkan melalui saluran "terpisah" dari pengembalian reguler. Itu berlaku di sini juga, meskipun tanggapan HTTP 200, 404, dan 500 adalah saluran yang sama dari sudut pandang tingkat rendah. Mereka terstandarisasi dan mudah dipisahkan sehingga kerangka kerja klien REST saya dapat dengan mudah mengaktifkan status itu untuk mengubahnya menjadi struktur yang tepat dalam bahasa saya; untuk melakukan hal yang sama dengan lapisan JSON (di mana Anda selalu mengatakan 200 dan memberi sayaDeviceInfo
pesan kesalahan atau salah) saya perlu menanamkan beberapa pengetahuan tentang skema JSON yang Anda gunakan.Jadi hanya gunakan 200 ketika Anda dapat mengembalikan nilai yang valid dari tipe yang diharapkan (itulah sebabnya
http://example.com/restapi/search-devices?colour=blue
dapat mengembalikan 200 dengan array kosong jika tidak ada perangkat biru; array kosong adalah array yang valid, dan jawaban yang masuk akal untuk permintaan "Saya ingin detail semua perangkat biru "). Jika tidak bisa, gunakan kode status non-200 yang paling tepat. Meskipun "perangkat 123 tidak ada" adalah respons yang tepat untuk "berikan saya detail perangkat 123", dan bukan kesalahan untuk server , ini merupakan pengecualian untuk harapan klien bahwa mereka akan mendapatkan kembaliDeviceInfo
dan harus tidak dikomunikasikan sebagai respons "di sini adalah apa yang Anda minta" normal.sumber
Anda bisa menggunakan kesalahan 422 Entitas yang tidak dapat diproses untuk membedakan dari 404 yang tidak ditemukan . 422 berarti server memahami permintaan tersebut tetapi tidak dapat memberikan respons yang tepat. Saya menggunakan kode ini pada situasi yang sama.
sumber
Kesalahan 500 biasanya menunjukkan bahwa permintaan membuat program sisi server macet; di lingkungan perusahaan kesalahan ini diperlakukan seperti telur di wajah dan sedang dihindari.
Kesalahan 4xx harus memberi sinyal kepada programmer bahwa titik akhir API (sumber daya) tidak ada. Akibatnya, setelah titik akhir yang tepat tercapai, penanganan kesalahan sejak saat itu adalah tanggung jawab programmer API yang harus ditangani dengan anggun, yaitu dengan pesan kesalahan dari 200 respons.
sumber
Meskipun w3 mencatat bahwa 404 digunakan ketika tidak ada respons lain yang berlaku , bukankah ini akan baik untuk respons 204 (Tidak Ada Konten)? Permintaan itu valid dari sudut pandang pemrosesan dan server memproses permintaan tersebut dan hasilnya. Itu sukses, yang condong ke arah respons 2xx. Tidak ada konten untuk permintaan khusus ini sehingga 204 memberi tahu pengguna bahwa tidak ada yang salah dengan permintaan mereka tetapi tidak ada di sana.
Anda juga bisa membuat kasus yang lemah bahwa 409 (Konflik) adalah respons yang sesuai. Meskipun 409 paling sering digunakan untuk POST, katanya
bisa dibilang tidak adanya id yang diminta adalah konflik di sini, dan kembali dalam pesan bahwa tidak ada id seperti itu dalam sistem adalah informasi yang cukup bagi pengguna untuk mengenali dan memperbaiki konflik.
sumber
Jawaban lain mengatasinya, tetapi saya hanya ingin menunjukkan bahwa kesalahan 500-seri berarti "Saya kacau." Dalam hal ini, "I" berarti API, sehingga kesalahan server tidak tertangani atau serupa. Kesalahan 400-seri berarti "Anda mengacaukan" - penelepon API mengirim sesuatu yang salah.
sumber
Pengguna lain telah memberikan jawaban yang valid untuk apa yang harus dilakukan jika Anda ingin membaca buku.
Namun saya menyarankan agar Anda membaca terlalu banyak tentang RESTfulness dan menjadi benar-benar halal sehubungan dengan itu.
REST adalah protokol yang berubah-ubah, karena jika Anda ingin membaca buku sambil menggunakannya, maka itu akan memaksa klien dan server untuk dibangun memiliki pengetahuan khusus tentang fakta bahwa mereka berkomunikasi melalui REST, jadi pada dasarnya protokol komunikasi spesifik menjadi digunakan tidak dapat disarikan keluar.
Ada pendekatan yang berbeda: sepenuhnya menghindari RESTfulness, dan menggunakannya hanya sebagai protokol komunikasi dan tidak ada yang lain. Ini berarti bahwa satu-satunya respons yang perlu dikembalikan adalah "HTTP 200 OK" dan "HTTP 500 Internal Server Error" karena sejauh menyangkut protokol komunikasi, setiap upaya untuk berkomunikasi hanya dapat memiliki dua hasil: baik permintaan berhasil dikirim ke server, atau tidak.
Apa yang terjadi setelah melahirkan, bukan urusan protokol komunikasi. Jadi, setelah server berhasil menerima permintaan, dan mulai memprosesnya, banyak kesalahan dapat terjadi, tetapi ini semua adalah kesalahan spesifik aplikasi yang bukan urusan protokol komunikasi untuk mengetahui apa pun. Mereka harus dikomunikasikan dalam muatan respon yang terlihat sangat sukses sejauh protokol komunikasi tahu.
Jadi, intinya adalah, saya akan merekomendasikan mengembalikan "HTTP 200 OK" dan dalam payload respons ("isi konten" dalam bahasa HTTP) memiliki kode kesalahan khusus aplikasi yang mengatakan "ID tidak ditemukan" atau apa pun.
sumber