Haruskah kode status HTTP digunakan untuk mewakili kesalahan logika bisnis di server?

20

Saya sedikit di persimpangan jalan dengan beberapa desain API untuk klien (JS di browser) untuk berbicara dengan server. Kami menggunakan Konflik HTTP 409 untuk mewakili kegagalan tindakan karena kunci pengaman berlaku. Kunci satefy mencegah devs membuat perubahan secara tidak sengaja dalam sistem produksi pelanggan kami. Saya telah ditugaskan menangani 409s sedikit lebih anggun pada klien untuk menunjukkan mengapa panggilan API tertentu gagal.

Solusi saya adalah untuk membungkus penangan kegagalan dari setiap panggilan AJAX kami yang akan menampilkan pemberitahuan pada klien ketika sesuatu gagal karena 409 - ini semua baik-baik saja dan bekerja dengan baik bersama kesalahan 4XX dan 5XX lainnya yang menggunakan mekanisme yang sama.

Masalah telah muncul ketika salah satu penangan rute kami merespons dengan 409 ketika menemukan kesalahan logika bisnis - pembungkus AJAX saya melaporkan bahwa kunci pengaman aktif, sementara penangan kegagalan klien yang ada melaporkan apa (yang menurutnya) masalah berdasarkan pada tubuh tanggapan. Solusi sederhana adalah mengubah respons pawang atau kode status yang kami gunakan untuk mewakili kunci pengaman.

Yang membawa saya ke persimpangan jalan: haruskah kode status HTTP bahkan digunakan untuk mewakili kesalahan logika bisnis? Pertanyaan ini membahas masalah yang sama yang saya hadapi tetapi tidak mendapatkan banyak daya tarik. Seperti yang disarankan dalam jawaban yang ditautkan, saya condong ke arah menggunakan HTTP 200 OK dengan badan yang sesuai untuk mewakili kegagalan dalam logika bisnis.

Adakah yang punya pendapat kuat di sini? Adakah yang bisa meyakinkan saya bahwa ini adalah cara yang salah untuk menggambarkan kegagalan?

Joe Shanahan
sumber
3
Saya ragu untuk mengirim pendapat sederhana saya sebagai jawaban. Singkatnya: Saya biasanya menghindari menggunakan kode status HTTP untuk mewakili kesalahan bisnis. Mereka hanya berkaitan dengan status komunikasi antara klien dan server. Kode status yang sesuai untuk mengembalikan validasi atau kesalahan logika bisnis adalah 400 Bad Request. Alasan pemisahan ini adalah karena sistem di masa depan, pengembang atau pembaca dokumen mungkin bingung dengan penyimpangan Anda dari standar di seluruh dunia.
Ivo Coumans
@IvoCoumans: tolong buat ini ^ jawaban agar saya bisa menjawabnya. 400 Bad Requestsebagai selimut, kode HTTP tampaknya paling baik untuk menutupi kesalahan logika bisnis sebagai kelas.
9000
Preferensi pribadi, tetapi saya cenderung menggunakan 400 Bad Requestketika data hilang atau tidak dapat dibaca / diuraikan. Yaitu data permintaan itu sendiri buruk dalam beberapa hal.
Kasey Speakman
Harap perluas apa yang Anda maksud dengan "kesalahan logika bisnis". Itu sangat kabur. Apakah maksud Anda input yang tidak valid sesuai dengan pemeriksaan validasi data (benar), input yang mungkin valid di beberapa titik waktu tetapi tidak valid dalam kondisi saat ini, atau bug dalam logika bisnis di mana ia menolak input yang valid?
jpmc26
@ jpmc26 Saya sengaja dibuat kabur karena itu adalah pertanyaan umum. Server mengatasi permintaan dengan baik tetapi memutuskan bahwa permintaan / pernyataan tidak masuk akal.
Joe Shanahan

Jawaban:

19

Kasey mencakup poin utama.

Gagasan kunci dalam api web apa pun: Anda mengadaptasi domain Anda agar terlihat seperti penyimpanan dokumen. DAPATKAN / PUT / POST / HAPUS dan sebagainya adalah semua cara berinteraksi dengan penyimpanan dokumen.

Jadi suatu cara berpikir tentang apa kode untuk digunakan, adalah untuk memahami apa operasi analog adalah di toko dokumen, dan apa kegagalan ini akan terlihat seperti di analog itu.

2xx sama sekali tidak cocok

Kelas kode status 2xx (Berhasil) menunjukkan bahwa permintaan klien berhasil diterima, dipahami, dan diterima.

5xx juga tidak cocok

Kelas 5xx (Kesalahan Server) kode status menunjukkan bahwa server sadar bahwa ia telah melakukan kesalahan

Dalam hal ini, server tidak melakukan kesalahan; sadar bahwa Anda tidak seharusnya mengubah sumber daya itu seperti itu saat ini.

Kesalahan logika bisnis (artinya invarian bisnis tidak mengizinkan pengeditan yang diusulkan saat ini) mungkin 409

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 mengirim kembali permintaan. Server HARUS menghasilkan payload yang mencakup informasi yang cukup bagi pengguna untuk mengenali sumber konflik.

Catat bit terakhir ini - muatan respons 409 harus mengkomunikasikan informasi kepada konsumen tentang apa yang salah, dan idealnya mencakup kontrol hypermedia yang mengarahkan konsumen ke sumber daya yang dapat membantu menyelesaikan konflik.

Solusi saya adalah untuk membungkus penangan kegagalan dari setiap panggilan AJAX kami yang akan menampilkan pemberitahuan pada klien ketika sesuatu gagal karena 409 - ini semua baik-baik saja dan bekerja dengan baik bersama kesalahan 4XX dan 5XX lainnya yang menggunakan mekanisme yang sama.

Dan saya akan menunjuk ini sebagai masalah; implementasi Anda di klien mengasumsikan bahwa kode status sudah cukup untuk mendefinisikan masalah. Alih-alih, kode klien Anda harus meninjau muatan, dan bertindak berdasarkan informasi yang tersedia di sana.

Lagi pula, bagaimana sebuah toko dokumen akan melakukannya

409  Conflict

your proposed change has been declined because ${REASON}.  
The following resolution protocols are available: ${LINKS[@]})

Pendekatan yang sama dengan a 400 Bad Requestjuga dapat diterima; yang kira-kira "diterjemahkan menjadi" Ada masalah dengan permintaan Anda. Kami tidak dapat diganggu untuk mencari tahu kode status mana yang paling cocok, jadi begini. Lihat payload untuk detailnya. "

Saya akan menggunakan 422. Input ini valid sehingga 400 bukan kode kesalahan yang tepat untuk digunakan

Spesifikasi WebDAV mencakup rekomendasi ini

Kode status 422 (Entitas yang Tidak Dapat Diproses) berarti server memahami jenis konten entitas permintaan (oleh karena itu kode status 415 (Jenis Media yang Tidak Didukung) tidak pantas), dan sintaks entitas permintaan itu benar (sehingga 400 (Permintaan Buruk) ) kode status tidak pantas) tetapi tidak dapat memproses instruksi yang terkandung. Sebagai contoh, kondisi kesalahan ini dapat terjadi jika badan permintaan XML berisi formulasi XML yang baik (yaitu, benar secara sintaksis), tetapi secara semestinya salah.

Saya tidak percaya itu cukup cocok (walaupun saya setuju bahwa itu menghilangkan keraguan 400sebagai alternatif). Interpretasi saya adalah itu 422berarti "Anda telah mengirim entitas yang salah" di mana 409"Anda mengirim entitas pada waktu yang salah".

Dengan kata lain, 422menunjukkan masalah dengan pesan permintaan dipertimbangkan secara terpisah, di mana 409menunjukkan bahwa pesan permintaan bertentangan dengan keadaan sumber daya saat ini.

Diskusi Ben Nadal tentang 422 mungkin berguna untuk dipertimbangkan.

VoiceOfUnreason
sumber
5
" Anda mengadaptasi domain Anda agar terlihat seperti toko dokumen " - Saya ingin melihat orang membaca ini, dan sepenuhnya memahami semua konsekuensi dan implikasi sebelum mereka memutuskan untuk (atau menentang) REST. Sangat.
JensG
"Kesalahan logika bisnis" terdengar seperti "input tidak valid," bagi saya, yang biasanya umumnya berupa 400, karena tidak ada kode kesalahan yang lebih spesifik untuk itu. Jika bukan input yang tidak valid, maka server memiliki bug dan 500 sesuai. Jawaban Anda tampaknya terlalu banyak berasumsi tentang sifat "kesalahan logika bisnis".
jpmc26
Saya akan menggunakan 422. Input ini valid sehingga 400 bukan kode kesalahan yang tepat untuk digunakan
Konrad
19

Dalam pengalaman saya, kode kesalahan HTTP tidak cukup untuk mewakili kesalahan bisnis. Namun, mereka berguna untuk mewakili kelas kesalahan.

Jadi, rekomendasi saya adalah menggunakan kode kesalahan HTTP untuk kategori kesalahan, tetapi pilih kesalahan spesifik untuk kegagalan logika bisnis (mis. 409 Konflik ... 200 OK akan menyesatkan di sini) dan memasukkan data dalam respons yang mengindikasikan kesalahan bisnis tertentu . Pastikan ini adalah bagian dari konten respons dan bukan teks status karena beberapa browser mengabaikan teks status kustom. Bahasa yang saya ingin gunakan memiliki Jenis Union yang nyaman untuk mewakili pesan. Tapi Anda juga bisa mendefinisikan konstanta string untuk kasus kesalahan.

Contohnya

// error with text response
409 Conflict "safety_lock_engaged"
409 Conflict "customer_not_eligible_for_selected_discount"
// warning with JSON response
202 Accepted { "backorderedProductIds": [ 37, 476 ] }
Kasey Speakman
sumber
Kode status 4xx di atas 400 memiliki arti yang sangat spesifik. Pilih 400 jika kasing Anda tidak secara khusus dicakup oleh yang lain.
jpmc26
@ jpmc26 Jika saya tidak menggunakan kode status dengan cara ini, maka mereka tidak pernah digunakan. Namun jangan ragu untuk menggunakannya dengan cara yang benar dan tepat dalam jawaban Anda.
Kasey Speakman
Dalam arti tertentu, Anda benar. Mereka tidak pernah digunakan. Makna yang dipilih untuk kode tertentu tampaknya tidak menjadi kasus penggunaan yang sangat umum untuk sebagian besar aplikasi. Tidak apa-apa. Ada banyak pengecualian yang kami tidak pernah menulis kode untuk menangkap, baik.
jpmc26
@ jpmc26 Yah, pengecualian bukan model terbaik untuk diikuti . Tapi tentu, silakan.
Kasey Speakman
Tidak melempar atau menangkap untuk jenis pengecualian tertentu adalah analog untuk tidak pernah menggunakan kode HTTP spesifik atau kode kesalahan lainnya. Saya berasumsi ini akan jelas. Apakah model pengecualian adalah "yang terbaik" sama sekali tidak relevan dengan intinya.
jpmc26
5

Secara umum, saya akan menghindari menggunakan kode status HTTP untuk mewakili kesalahan logika bisnis tertentu . Ini karena mereka sudah memiliki makna semantik yang didefinisikan oleh standar di seluruh dunia. Sistem lain, pengembang baru dan seterusnya akan bingung oleh penyimpangan standar Anda.

Apa yang saya temukan dalam penelitian baru-baru ini, serupa, adalah bahwa itu secara umum diterima untuk digunakan 400 Bad Requestdalam kasus kesalahan validasi dan semacamnya. Dengan cara ini, Anda menggunakan satu kode status untuk semua kesalahan logika bisnis.

Secara kebetulan, 409harus digunakan ketika sumber daya telah berubah saat Anda mengeditnya dan mencoba menyimpannya lagi.

Ivo Coumans
sumber
4

Anda dapat menggunakan "Permintaan Buruk" dan menyertakan id aturan bisnis yang dilanggar plus beberapa detail lainnya di badan respons.

nonekoneks
sumber
Saya tidak tahu mengapa ini diturunkan. Ini adalah bagaimana perusahaan dapat mengembalikan pengecualian bisnis.
Skadoosh