ควรใช้รหัสสถานะ HTTP เพื่อแสดงถึงข้อผิดพลาดทางตรรกะทางธุรกิจบนเซิร์ฟเวอร์หรือไม่?


20

ฉันกำลังอยู่ระหว่างทางแยกที่มีการออกแบบ API บางอย่างสำหรับลูกค้า (JS ในเบราว์เซอร์) เพื่อพูดคุยกับเซิร์ฟเวอร์ เราใช้ HTTP 409 Conflict เพื่อแสดงถึงความล้มเหลวของการกระทำเนื่องจากมีการล็อคเพื่อความปลอดภัย ล็อค satefy ป้องกันไม่ให้ devs ทำการเปลี่ยนแปลงในระบบการผลิตของลูกค้าโดยไม่ได้ตั้งใจ ฉันได้รับมอบหมายให้จัดการ 409 บิตให้กับลูกค้าอย่างอ่อนโยนยิ่งขึ้นเพื่อระบุว่าเหตุใดการเรียก API เฉพาะจึงล้มเหลว

โซลูชันของฉันคือการตัดตัวจัดการความล้มเหลวของการโทร AJAX ใด ๆ ของเราซึ่งจะแสดงการแจ้งเตือนลูกค้าเมื่อมีบางอย่างล้มเหลวเนื่องจาก 409 - ทั้งหมดนี้ใช้ได้และทำงานได้ดีพร้อมกับข้อผิดพลาด 4XX และ 5XX อื่น ๆ ที่ใช้กลไกเดียวกัน

มีปัญหาเกิดขึ้นที่หนึ่งในตัวจัดการเส้นทางของเราตอบสนองกับ 409s เมื่อพบข้อผิดพลาดทางธุรกิจตรรกะ - AJAX wrapper ของฉันรายงานว่าล็อคความปลอดภัยอยู่ในขณะที่ลูกค้าจัดการความล้มเหลวที่มีอยู่รายงานสิ่งที่มันคิดว่ามันขึ้นอยู่กับร่างกาย ของการตอบสนอง วิธีแก้ปัญหาง่ายๆคือเปลี่ยนการตอบสนองของผู้จัดการหรือรหัสสถานะที่เราใช้เพื่อเป็นตัวแทนของล็อคความปลอดภัย

ซึ่งนำฉันไปสู่ทางแยกของฉัน: ควรใช้รหัสสถานะ HTTP เพื่อแสดงถึงข้อผิดพลาดทางตรรกะทางธุรกิจหรือไม่ คำถามนี้เน้นปัญหาเดียวกันกับที่ฉันเผชิญ แต่ก็ไม่ได้รับแรงฉุดมากนัก ตามที่แนะนำในคำตอบที่เชื่อมโยงกันฉันกำลังโน้มตัวไปใช้ HTTP 200 OK กับเนื้อหาที่เหมาะสมเพื่อแสดงถึงความล้มเหลวภายในตรรกะทางธุรกิจ

ใครบ้างมีความคิดเห็นที่แข็งแกร่งที่นี่? ทุกคนสามารถโน้มน้าวฉันได้ไหมว่านี่เป็นวิธีที่ผิดในการแสดงถึงความล้มเหลว?


3
ฉันลังเลที่จะโพสต์ความเห็นง่ายๆของฉันเป็นคำตอบ กล่าวโดยย่อ: ฉันมักหลีกเลี่ยงการใช้รหัสสถานะ HTTP เพื่อแสดงถึงข้อผิดพลาดทางธุรกิจ พวกเขาควรเกี่ยวข้องกับสถานะของการสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์เท่านั้น 400 Bad Requestรหัสสถานะเหมาะสำหรับการกลับมาตรวจสอบหรือตรรกะทางธุรกิจที่จะเป็นข้อผิดพลาด สาเหตุของการแยกนี้เป็นเพราะระบบในอนาคต devs หรือผู้อ่านเอกสารอาจสับสนโดยการเบี่ยงเบนของมาตรฐานทั่วโลก
Ivo Coumans

@IvoCoumans: โปรดทำให้ ^ คำตอบนี้เพื่อให้ฉันสามารถ upvote ได้ 400 Bad Requestในฐานะที่เป็นรหัสผ้าห่ม HTTP ที่ดีที่สุดที่จะครอบคลุมข้อผิดพลาดตรรกะทางธุรกิจเป็นชั้นเรียน
9000

การตั้งค่าส่วนตัว แต่ฉันมักจะใช้400 Bad Requestเมื่อข้อมูลหายไปหรือไม่สามารถอ่าน / แยกวิเคราะห์ได้ นั่นคือข้อมูลคำขอของตัวเองไม่ดีอย่างใด
Kasey Speakman

โปรดขยายสิ่งที่คุณหมายถึงโดย "ข้อผิดพลาดตรรกะทางธุรกิจ" มันคลุมเครือมาก คุณหมายถึงอินพุตที่ไม่ถูกต้องสำหรับการตรวจสอบความถูกต้องของข้อมูล (ที่ถูกต้อง) การป้อนข้อมูลที่อาจใช้งานได้ในบางช่วงเวลา แต่ไม่ถูกต้องในสถานะปัจจุบันหรือข้อผิดพลาดในตรรกะทางธุรกิจที่ปฏิเสธอินพุตที่ถูกต้อง
jpmc26

@ jpmc26 ฉันถูกคลุมเครือโดยเจตนาเพราะเป็นคำถามทั่วไป เซิร์ฟเวอร์จัดการกับคำขอได้ดี แต่ตัดสินใจว่าการสอบถาม / การยืนยันนั้นไม่สมเหตุสมผล
Joe Shanahan

คำตอบ:


19

Kaseyครอบคลุมประเด็นหลัก

แนวคิดหลักในเว็บ API ใด ๆ : คุณกำลังปรับโดเมนของคุณให้ดูเหมือนกับที่เก็บเอกสาร GET / PUT / POST / DELETE และอื่น ๆ ล้วนเป็นวิธีการโต้ตอบกับที่เก็บเอกสาร

ดังนั้นวิธีคิดเกี่ยวกับสิ่งที่รหัสเพื่อใช้คือการเข้าใจว่าการดำเนินการที่คล้ายคลึงกันอยู่ในร้านเอกสารและสิ่งที่ล้มเหลวนี้จะมีลักษณะเหมือนในอนาล็อกที่

2xx ไม่เหมาะสมอย่างสมบูรณ์

รหัสสถานะคลาส 2xx (สำเร็จ) ระบุว่าคำขอของลูกค้าได้รับเข้าใจและยอมรับเรียบร้อยแล้ว

5xx ก็ไม่เหมาะสมเช่นกัน

รหัสสถานะคลาส 5xx (ข้อผิดพลาดของเซิร์ฟเวอร์) บ่งชี้ว่าเซิร์ฟเวอร์ทราบว่ามีข้อผิดพลาด

ในกรณีนี้เซิร์ฟเวอร์ไม่ได้ทำผิด โปรดทราบว่าคุณไม่ควรแก้ไขทรัพยากรดังกล่าวในเวลานี้

ข้อผิดพลาดตรรกะทางธุรกิจ (หมายถึงว่าค่าคงที่ทางธุรกิจไม่อนุญาตให้มีการแก้ไขที่เสนอในขณะนี้) น่าจะเป็น409

รหัสสถานะ 409 (ความขัดแย้ง) บ่งชี้ว่าการร้องขอไม่สามารถดำเนินการให้เสร็จสมบูรณ์ได้เนื่องจากข้อขัดแย้งกับสถานะปัจจุบันของทรัพยากรเป้าหมาย รหัสนี้ใช้ในสถานการณ์ที่ผู้ใช้อาจสามารถแก้ไขข้อขัดแย้งและส่งคำร้องขอใหม่ได้ เซิร์ฟเวอร์ SHOULD สร้าง payload ที่มีข้อมูลเพียงพอสำหรับผู้ใช้ในการรับรู้ถึงแหล่งที่มาของความขัดแย้ง

หมายเหตุบิตสุดท้ายนี้ส่วนของการตอบกลับ 409 ควรสื่อสารข้อมูลไปยังผู้บริโภคเกี่ยวกับสิ่งที่ผิดพลาดและรวมถึงการควบคุมสื่อหลายมิติที่นำผู้บริโภคไปสู่ทรัพยากรที่สามารถช่วยแก้ไขความขัดแย้งได้

โซลูชันของฉันคือการตัดตัวจัดการความล้มเหลวของการโทร AJAX ใด ๆ ของเราซึ่งจะแสดงการแจ้งเตือนลูกค้าเมื่อมีบางอย่างล้มเหลวเนื่องจาก 409 - ทั้งหมดนี้ใช้ได้และทำงานได้ดีพร้อมกับข้อผิดพลาด 4XX และ 5XX อื่น ๆ ที่ใช้กลไกเดียวกัน

และฉันจะชี้ให้เห็นว่านี่เป็นปัญหา การใช้งานของคุณที่ไคลเอ็นต์ถือว่ารหัสสถานะเพียงพอที่จะกำหนดปัญหา แต่รหัสลูกค้าของคุณควรตรวจสอบน้ำหนักบรรทุกและดำเนินการกับข้อมูลที่มีอยู่

นั่นคือวิธีที่เก็บเอกสารจะทำอย่างไร

409  Conflict

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

วิธีการเดียวกันกับที่400 Bad Requestจะเป็นที่ยอมรับ; ซึ่งแปลว่า "แปลว่า" มีปัญหากับคำขอของคุณ เราไม่สามารถทราบได้ว่ารหัสสถานะใดเหมาะสมที่สุดดังนั้นคุณจึงไปที่นี่ ดูที่ส่วนของข้อมูลเพื่อดูรายละเอียด "

ฉันจะใช้ 422 อินพุตถูกต้องดังนั้น 400 ไม่ใช่รหัสข้อผิดพลาดที่ถูกต้องที่จะใช้

ข้อมูลจำเพาะ WebDAV มีคำแนะนำนี้

รหัสสถานะ 422 (หน่วยประมวลผลไม่ได้) หมายความว่าเซิร์ฟเวอร์เข้าใจประเภทเนื้อหาของเอนทิตีที่ร้องขอ (ดังนั้นรหัสสถานะ 415 (ประเภทสื่อที่ไม่สนับสนุน) ไม่เหมาะสม) และไวยากรณ์ของเอนทิตีร้องขอถูกต้อง (ดังนั้น 400 (คำขอไม่ถูกต้อง) ) รหัสสถานะไม่เหมาะสม) แต่ไม่สามารถประมวลผลคำแนะนำที่มีอยู่ ตัวอย่างเช่นเงื่อนไขข้อผิดพลาดนี้อาจเกิดขึ้นหากเนื้อความคำขอ XML มีรูปแบบที่ถูกต้อง (เช่นถูกต้องทางไวยากรณ์) แต่คำสั่ง XML ผิดพลาดทางความหมาย

ฉันไม่เชื่อว่าเป็นการแข่งขัน (แม้ว่าฉันยอมรับว่ามันเป็นข้อสงสัยบางอย่างเกี่ยว400กับทางเลือก) การตีความของฉันหมาย422ถึง "คุณส่งเอนทิตีผิด" อยู่ที่ไหน409"คุณส่งเอนทิตีผิดเวลา"

ใส่อีกวิธีหนึ่ง422ระบุว่ามีปัญหากับข้อความคำขอที่พิจารณาแยกต่างหากโดยที่409ระบุว่าข้อความคำขอนั้นขัดแย้งกับสถานะปัจจุบันของทรัพยากร

การอภิปรายของ Ben Nadal ใน 422อาจเป็นประโยชน์ในการพิจารณา


5
" คุณกำลังปรับโดเมนของคุณให้ดูเหมือนร้านขายเอกสาร " - ฉันชอบที่จะเห็นผู้คนอ่านสิ่งนี้และทำความเข้าใจกับผลลัพธ์และผลกระทบทั้งหมดก่อนที่พวกเขาจะตัดสินใจ (หรือต่อต้าน) REST จริงๆ.
JensG

"ข้อผิดพลาดตรรกะทางธุรกิจ" ดูเหมือนว่า "อินพุตไม่ถูกต้อง" สำหรับฉันซึ่งโดยทั่วไปจะเป็น 400 ตรงเนื่องจากไม่มีรหัสข้อผิดพลาดเฉพาะเจาะจงมากขึ้น หากไม่ใช่อินพุตที่ไม่ถูกต้องแสดงว่าเซิร์ฟเวอร์มีข้อบกพร่องและ 500 เหมาะสม คำตอบของคุณดูเหมือนจะสมมติมากเกินไปเกี่ยวกับลักษณะของ "ข้อผิดพลาดทางตรรกะทางธุรกิจ"
jpmc26

ฉันจะใช้ 422 อินพุตถูกต้องดังนั้น 400 ไม่ใช่รหัสข้อผิดพลาดที่ถูกต้องในการใช้
Konrad

19

จากประสบการณ์ของฉันรหัสข้อผิดพลาด HTTP ไม่เพียงพอที่จะแสดงถึงข้อผิดพลาดทางธุรกิจ อย่างไรก็ตามมันมีประโยชน์ในการแสดงคลาสของข้อผิดพลาด

ดังนั้นคำแนะนำของฉันคือการใช้รหัสข้อผิดพลาด HTTP สำหรับหมวดหมู่ของข้อผิดพลาด แต่เลือกข้อผิดพลาดเฉพาะสำหรับความล้มเหลวของตรรกะทางธุรกิจ (เช่น 409 ข้อขัดแย้ง ... 200 OK จะทำให้เข้าใจผิดที่นี่) และรวมข้อมูลในการตอบสนอง . ตรวจสอบให้แน่ใจว่านี่เป็นส่วนหนึ่งของเนื้อหาการตอบกลับไม่ใช่ข้อความแสดงสถานะเนื่องจากเบราว์เซอร์บางตัวไม่สนใจข้อความสถานะที่กำหนดเอง ภาษาที่ฉันชอบใช้มีประเภทของสหภาพซึ่งสะดวกต่อการแสดงข้อความ แต่คุณสามารถกำหนดค่าคงที่สตริงสำหรับกรณีข้อผิดพลาด

ตัวอย่าง

// 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 ] }

รหัสสถานะ 4xx ที่สูงกว่า 400 มีความหมายที่เฉพาะเจาะจงมาก เลือก 400 หากกรณีของคุณไม่ได้รับการคุ้มครองโดยเฉพาะ
jpmc26

@ jpmc26 หากฉันไม่ใช้รหัสสถานะด้วยวิธีนี้พวกเขาจะไม่เคยใช้ แต่อย่าลังเลที่จะใช้คำตอบที่ถูกต้องและเหมาะสม
Kasey Speakman

ในบางแง่คุณพูดถูก พวกเขาไม่เคยใช้ ความหมายที่เลือกไว้สำหรับรหัสเฉพาะนั้นไม่ได้เป็นกรณีการใช้งานทั่วไปสำหรับแอปพลิเคชันส่วนใหญ่ ไม่เป็นไร. มีข้อยกเว้นมากมายที่เราไม่เคยเขียนโค้ดเพื่อตรวจจับเช่นกัน
jpmc26

@ jpmc26 ข้อยกเว้นกันไม่ได้รูปแบบที่ยิ่งใหญ่ที่สุดที่จะปฏิบัติตาม แต่แน่นอนไปข้างหน้า
Kasey Speakman

การไม่ขว้างหรือจับการยกเว้นประเภทเฉพาะนั้นเป็นแบบอะนาล็อกที่ไม่เคยใช้รหัส HTTP เฉพาะหรือรหัสข้อผิดพลาดอื่นใด ฉันคิดว่ามันจะชัดเจน แบบจำลองข้อยกเว้นคือ "ดีที่สุด" หรือไม่นั้นไม่เกี่ยวข้องกับประเด็นทั้งหมด
jpmc26

5

โดยทั่วไปฉันจะหลีกเลี่ยงการใช้รหัสสถานะ HTTP เพื่อแสดงถึงข้อผิดพลาดทางตรรกะทางธุรกิจที่เฉพาะเจาะจง นี่เป็นเพราะพวกเขามีความหมายเชิงความหมายที่กำหนดโดยมาตรฐานทั่วโลก ระบบอื่น ๆ devs ใหม่และอื่น ๆ จะสับสนโดยการเบี่ยงเบนมาตรฐานของคุณ

สิ่งที่ฉันพบในการวิจัยที่คล้ายกันเมื่อเร็ว ๆ นี้ก็คือมันเป็นที่ยอมรับกันโดยทั่วไปว่าจะใช้400 Bad Requestในกรณีที่ข้อผิดพลาดในการตรวจสอบและเช่น ด้วยวิธีนี้คุณใช้รหัสสถานะหนึ่งรหัสสำหรับข้อผิดพลาดทางตรรกะทางธุรกิจทั้งหมด

อนึ่ง409ควรจะใช้เมื่อเป็นทรัพยากรที่มีการเปลี่ยนแปลงในขณะที่คุณกำลังแก้ไขและพยายามบันทึกอีกครั้ง


4

คุณสามารถใช้ "คำขอไม่ถูกต้อง" และใส่รหัสของกฎธุรกิจที่ละเมิดรวมทั้งรายละเอียดเพิ่มเติมบางส่วนเกี่ยวกับเนื้อหาของการตอบกลับ


ฉันไม่ทราบว่าเวย์นี้ถูกโหวต นี่คือวิธีที่ บริษัท ต่างๆจะส่งคืนข้อยกเว้นทางธุรกิจ
Skadoosh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.