การตอบกลับข้อผิดพลาดของ API ของคุณเป็นส่วนหนึ่งของสัญญาของ API ลูกค้าจะแยกวิเคราะห์ข้อผิดพลาดเหล่านั้น ตรรกะการลองใหม่จะแยกสาขาจากข้อผิดพลาดเหล่านั้น และวิศวกรสนับสนุนจะค้นหาข้อผิดพลาดเหล่านั้นตอนตี 2 ทว่าทีมส่วนใหญ่กลับออกแบบเส้นทางที่สมบูรณ์แบบโดยละเอียดและปล่อยให้ข้อผิดพลาดเกิดขึ้นตามที่เฟรมเวิร์กทำโดยค่าเริ่มต้น นั่นคือสาเหตุที่คุณลงเอยด้วยรูปแบบข้อผิดพลาดที่แตกต่างกันสามแบบใน API เดียว การตอบกลับ 200 ที่ห่อหุ้ม "success": false และ stack trace ที่รั่วไหลโครงสร้างฐานข้อมูลของคุณสู่สาธารณะบนอินเทอร์เน็ต
คู่มือนี้ครอบคลุมแนวทางปฏิบัติที่ดีที่สุดในการจัดการข้อผิดพลาดของ API สำหรับบริการ REST ตั้งแต่ต้นจนจบ: การเลือกสถานะโค้ดที่ถูกต้อง การกำหนดมาตรฐานรูปแบบข้อผิดพลาดเดียวด้วย RFC 9457 Problem Details การแยกโค้ดที่เครื่องอ่านได้ออกจากข้อความที่มนุษย์อ่านได้ การทำเครื่องหมายข้อผิดพลาดที่สามารถลองใหม่ได้ และการเก็บความลับออกจากคำตอบ คู่มือนี้ต่อยอดจากบทวิเคราะห์ของเราเกี่ยวกับ สถานะโค้ด HTTP ที่ API ของ REST ควรใช้ และเพิ่มการตัดสินใจระดับสัญญาที่คู่มือนี้เปิดค้างไว้ คุณจะได้เห็นวิธีทดสอบเส้นทางความล้มเหลวทุกเส้นทางใน Apidog เพราะสัญญาข้อผิดพลาดที่คุณไม่เคยทดสอบคือสัญญาที่คุณไม่มี
เริ่มต้นด้วยสถานะโค้ด ไม่ใช่เนื้อหา
HTTP มีความหมายของข้อผิดพลาดเบื้องต้นให้คุณใช้งานฟรี RFC 9110 กำหนดประเภทของสถานะโค้ด: 4xx หมายถึงไคลเอนต์ทำบางอย่างผิดพลาด และการส่งคำขอเดิมซ้ำจะล้มเหลวอีกครั้ง; 5xx หมายถึงเซิร์ฟเวอร์ล้มเหลว และคำขอของไคลเอนต์อาจจะถูกต้อง ทำความเข้าใจความแตกต่างนี้ให้ถูกต้องก่อนที่คุณจะเขียนโค้ดสำหรับเนื้อหาข้อผิดพลาดแม้แต่บรรทัดเดียว เพราะไคลเอนต์ทั่วไป พร็อกซี แคช และไลบรารีการลองใหม่ทั้งหมดจะแยกสาขาตามสถานะโค้ดโดยไม่ต้องอ่าน JSON ของคุณเลย
ข้อผิดพลาดที่พบบ่อยที่สุดมักจะรวมกลุ่มกันอยู่ในคู่ที่ดูคล้ายกันจำนวนหนึ่ง เปิด ข้อมูลอ้างอิงสถานะโค้ด HTTP ของ MDN ไว้ในขณะที่คุณออกแบบ และใช้ตารางการตัดสินใจนี้สำหรับโค้ดที่ทำให้ทีมสับสน
| สถานการณ์ | ใช้ | ไม่ใช่ | ทำไม |
|---|---|---|---|
| คำขอผิดรูปแบบ: JSON เสีย, ประเภทเนื้อหาไม่ถูกต้อง, ฟิลด์ที่จำเป็นหายไป | 400 Bad Request | 422 | เซิร์ฟเวอร์ไม่สามารถแยกวิเคราะห์หรือทำความเข้าใจคำขอได้เลย |
| คำขอที่ถูกรูปแบบแต่ละเมิดกฎความหมาย: จำนวนเงินติดลบ, สกุลเงินไม่รองรับ | 422 Unprocessable Content | 400 | ไวยากรณ์ถูกต้อง แต่ค่าไม่ถูกต้อง |
| ไม่มีข้อมูลประจำตัว หรือโทเค็นหมดอายุ/ไม่ถูกต้อง | 401 Unauthorized | 403 | ไคลเอนต์ยังไม่ได้พิสูจน์ว่าตนเป็นใคร ส่ง WWW-Authenticate |
| ข้อมูลประจำตัวถูกต้อง แต่สิทธิ์ไม่เพียงพอ | 403 Forbidden | 401 | รู้จักตัวตนแล้ว; การเข้าถึงถูกปฏิเสธ การยืนยันตัวตนใหม่ไม่ช่วยอะไร |
| ทรัพยากรไม่เคยมีอยู่ หรือคุณจะไม่ยืนยันว่ามีอยู่ | 404 Not Found | 410 | ค่าเริ่มต้นที่ปลอดภัย; ยังซ่อนทรัพยากรจากการตรวจสอบโดยไม่ได้รับอนุญาต |
| ทรัพยากรเคยมีอยู่และถูกลบออกไปอย่างจงใจและถาวร | 410 Gone | 404 | บอกไคลเอนต์และโปรแกรมรวบรวมข้อมูลให้ลบข้อมูลอ้างอิง |
| ความขัดแย้งของสถานะ: คีย์ซ้ำ, เวอร์ชันเก่า, การแก้ไขชนกัน | 409 Conflict | 400 | คำขอถูกต้องแต่ขัดแย้งกับสถานะทรัพยากรปัจจุบัน |
| ไคลเอนต์เกินขีดจำกัดการเรียกใช้ | 429 Too Many Requests | 503 | ควรใส่ Retry-After เสมอเพื่อให้ไคลเอนต์ถอยกลับได้อย่างถูกต้อง |
| ข้อยกเว้นที่ไม่ได้จัดการในโค้ดของคุณ | 500 Internal Server Error | 502 | เซิร์ฟเวอร์ของคุณขัดข้อง |
| บริการต้นน้ำส่งข้อมูลขยะกลับมาที่เกตเวย์ของคุณ | 502 Bad Gateway | 500 | ความล้มเหลวอยู่หลังส่วนปลาย ไม่ใช่ที่ส่วนปลาย |
| เซิร์ฟเวอร์โอเวอร์โหลดหรืออยู่ระหว่างการบำรุงรักษา | 503 Service Unavailable | 500 | ชั่วคราวตามคำนิยาม; เพิ่ม Retry-After เมื่อทำได้ |
| บริการต้นน้ำหมดเวลา | 504 Gateway Timeout | 500 | แยกแยะ "การพึ่งพาที่ช้า" ออกจาก "โค้ดเสีย" |
สองข้อนี้สมควรได้รับการเน้นเป็นพิเศษ ประการแรก 401 กับ 403 เป็นขอบเขตความปลอดภัย ไม่ใช่ทางเลือกสไตล์: การคืนค่า 403 ให้ผู้เรียกที่ยังไม่ได้ยืนยันตัวตนจะเผยแพร่ข้อเท็จจริงว่าทรัพยากรนั้นมีอยู่ ประการที่สอง 429 ที่ไม่มี Retry-After จะทำให้ไคลเอนต์โจมตีคุณซ้ำๆ ในลูปที่ไม่สิ้นสุด หากคุณจำกัดอัตราการเรียกใช้ ซึ่งคุณควรทำ ให้จับคู่สถานะกับสัญญาณการถอยกลับที่ชัดเจน; คู่มือของเราเกี่ยวกับการ จำกัดอัตราการเรียกใช้ API ครอบคลุมการคำนวณส่วนหัวและอัลกอริทึมเบื้องหลัง
รูปแบบเนื้อหาข้อผิดพลาดเดียว: RFC 9457 Problem Details
เมื่อสถานะโค้ดถูกต้องแล้ว ทุกข้อผิดพลาดที่ API ของคุณส่งคืนควรใช้ประเภทสื่อและสคีมาเดียวกัน คำตอบมาตรฐานคือ RFC 9457 Problem Details ซึ่งให้บริการเป็น application/problem+json โดยกำหนดสมาชิกหลักห้าตัว: type (URI ที่ระบุหมวดหมู่ข้อผิดพลาด), title (สรุปสั้นๆ ที่มนุษย์อ่านได้), status (โค้ด HTTP ซ้ำเพื่อความสะดวก), detail (สิ่งที่ผิดพลาดในเหตุการณ์นี้) และ instance (URI สำหรับความล้มเหลวเฉพาะนี้) ส่วนอื่นๆ จะอยู่ในส่วนขยายที่คุณกำหนดเอง
เราจะไม่สรุปข้อมูลจำเพาะอีกครั้งที่นี่; คำอธิบาย RFC 9457 ของเรา จะอธิบายสมาชิกแต่ละตัว กฎการลงทะเบียน และวิธีที่มันมาแทนที่ RFC 7807 สิ่งที่สำคัญสำหรับสัญญาของคุณคือรูปแบบ: ซองจดหมายมาตรฐาน, ส่วนขยายที่กำหนดเอง นี่คือข้อผิดพลาดในการตรวจสอบความถูกต้องบน endpoint การชำระเงิน
POST /v1/payments HTTP/1.1
Content-Type: application/json
{ "amount": -1400, "currency": "USD", "source": "card_8xKt2" }
HTTP/1.1 422 Unprocessable Content
Content-Type: application/problem+json
{
"type": "https://api.example.com/problems/validation-error",
"title": "Request validation failed",
"status": 422,
"detail": "ฟิลด์อย่างน้อยหนึ่งฟิลด์ไม่ผ่านการตรวจสอบความถูกต้อง",
"instance": "/v1/payments/requests/req_9f3c1a7b",
"code": "PAYMENT_VALIDATION_FAILED",
"errors": [
{
"field": "amount",
"code": "AMOUNT_NOT_POSITIVE",
"message": "จำนวนเงินต้องเป็นจำนวนเต็มบวกในหน่วยย่อย"
}
],
"request_id": "req_9f3c1a7b"
}
อาร์เรย์ errors[] เป็นส่วนขยาย และเป็นส่วนที่ลูกค้าชอบมากที่สุด: ช่วยให้ส่วนหน้าสามารถจับคู่ความล้มเหลวแต่ละครั้งกับฟิลด์ฟอร์มที่ถูกต้องแม่นยำ แทนที่จะแสดงแบนเนอร์ที่คลุมเครือเพียงอันเดียว เก็บพาธฟิลด์ในรูปแบบที่เสถียร (JSON Pointer หรือ dotted paths, เลือกอย่างใดอย่างหนึ่ง) เพื่อให้โค้ดไคลเอนต์สามารถผูกเข้าด้วยกันได้โดยโปรแกรม
กฎหนึ่งข้อช่วยลดความยุ่งยากได้มากที่สุด: ส่งคืนรูปแบบนี้สำหรับข้อผิดพลาดทุกประเภท รวมถึงข้อผิดพลาดที่เฟรมเวิร์กหรือเกตเวย์ของคุณสร้างขึ้น ไคลเอนต์ที่ได้รับ Problem Details จากตัวจัดการของคุณแต่ได้ HTML จากหน้า 502 ของ Load Balancer ของคุณยังคงต้องเขียนตัวแยกวิเคราะห์ถึงสองตัว
โค้ดที่เครื่องอ่านได้เทียบกับข้อความที่มนุษย์อ่านได้
สังเกตตัวอย่างที่มีทั้งฟิลด์ code และ message สิ่งนี้จงใจทำขึ้นเพื่อกลุ่มผู้ใช้ที่แตกต่างกัน และไม่ควรรวมเป็นสตริงเดียว
โค้ดที่เครื่องอ่านได้ (AMOUNT_NOT_POSITIVE, CURRENCY_UNSUPPORTED, IDEMPOTENCY_KEY_REUSED) คือสัญญา ลูกค้าจะแยกสาขาตามโค้ดเหล่านี้ ดังนั้นจึงต้องเสถียร มีเอกสารประกอบ และนับได้ ห้ามให้ลูกค้าแยกวิเคราะห์ข้อความ; ทันทีที่ใครบางคนเขียน if (message.includes("positive")) การแก้ไขข้อความของคุณจะกลายเป็นการเปลี่ยนแปลงที่ส่งผลกระทบต่อระบบ
ข้อความที่มนุษย์อ่านได้นั้นตรงกันข้าม: สามารถปรับปรุงได้ตลอดเวลา เขียนขึ้นสำหรับนักพัฒนาที่อ่านบันทึก และไม่ควรมีผลต่อการทำงาน ระบุว่าอะไรล้มเหลวและสิ่งที่แก้ไขแล้วจะเป็นอย่างไร: "จำนวนเงินต้องเป็นจำนวนเต็มบวกในหน่วยย่อย" ดีกว่า "จำนวนเงินไม่ถูกต้อง" หากคุณต้องการแปล ให้แปลข้อความและปล่อยโค้ดไว้ตามเดิม
การแบ่งแยกนี้มีความสำคัญมากยิ่งขึ้นในปัจจุบัน เนื่องจากผู้บริโภค API รวมถึงตัวแทนอิสระ ไคลเอนต์ที่ใช้ LLM สามารถกู้คืนได้ดีกว่ามากจากข้อผิดพลาดที่มีโครงสร้างและอธิบายตนเองได้ เราครอบคลุมมุมมองนั้นใน การออกแบบข้อผิดพลาด API สำหรับ AI agents
สิ่งที่ไม่ควรมีในการตอบกลับข้อผิดพลาด
การตอบกลับข้อผิดพลาดเป็นช่องทางสอดแนมที่ผู้โจมตีชื่นชอบ เนื่องจากความล้มเหลวที่ไม่ได้จัดการมักจะให้ข้อมูลมากเกินไป มิดเดิลแวร์ข้อผิดพลาดของคุณควรรับประกันว่าไม่มีสิ่งใดต่อไปนี้จะไปถึงไคลเอนต์:
- Stack trace, ชื่อคลาส หรือพาธไฟล์
- SQL ดิบ, ส่วนย่อยของคิวรี่ หรือข้อผิดพลาดของ ORM
- ชื่อโฮสต์ภายใน, IP, พอร์ต หรือชื่อบริการ
- เวอร์ชันไลบรารีและสตริงแบนเนอร์ของเฟรมเวิร์ก
- ความลับ, โทเค็น หรือสตริงการเชื่อมต่อที่ฝังอยู่ในข้อความข้อยกเว้น
- การมีอยู่ของบัญชีผู้ใช้ (ในการเข้าสู่ระบบและการรีเซ็ตรหัสผ่าน ให้รักษาความล้มเหลวให้สมมาตร)
รูปแบบนั้นง่าย: ดักจับทุกอย่างที่ขอบเขต บันทึกข้อยกเว้นทั้งหมดทางฝั่งเซิร์ฟเวอร์พร้อม ID คำขอ และส่งคืนเนื้อหา Problem Details ทั่วไปพร้อม ID เดียวกันนั้น ไคลเอนต์จะได้รับ "detail": "An internal error occurred", "request_id": "req_51ad0" บันทึกของคุณจะได้รับข้อมูลจริง และฝ่ายสนับสนุนสามารถเชื่อมโยงทั้งสองได้
ทำเครื่องหมายข้อผิดพลาดว่าสามารถลองใหม่ได้หรือสิ้นสุด
ทุกข้อผิดพลาดที่คุณส่งคืนจะตอบคำถามที่ไคลเอนต์กำลังจะถาม: ฉันควรลองสิ่งนี้อีกครั้งหรือไม่? ใส่คำตอบลงในสัญญาแทนที่จะปล่อยให้แต่ละทีมไคลเอนต์เดา
สถานะโค้ดมีความหมายเริ่มต้น 429, 502, 503 และ 504 สามารถลองใหม่ได้ด้วย exponential backoff และ jitter 500 คลุมเครือแต่โดยทั่วไปแล้วคุ้มค่าที่จะลองใหม่อย่างระมัดระวังหนึ่งครั้ง โค้ด 4xx อื่นๆ เกือบทั้งหมดเป็นแบบสิ้นสุด: การลองใหม่ 401, 403, 404 หรือ 422 ด้วยคำขอเดิมจะทำให้สิ้นเปลืองโควต้าและปนเปื้อนบันทึก การหมดเวลาสมควรได้รับการดูแลเป็นพิเศษ เนื่องจากคำขออาจสำเร็จหลังจากไคลเอนต์ยอมแพ้ นั่นคือปัญหา 408 request timeout แบบคลาสสิก และเป็นเหตุผลว่าทำไม endpoint ที่มีการเปลี่ยนแปลงข้อมูลควรรองรับ idempotency keys เพื่อให้การชำระเงินที่ลองใหม่ไม่สามารถเรียกเก็บเงินซ้ำได้สองครั้ง
คุณยังสามารถระบุความสามารถในการลองใหม่ได้อย่างชัดเจนด้วยส่วนขยาย:
{
"type": "https://api.example.com/problems/rate-limited",
"title": "Too many requests",
"status": 429,
"code": "RATE_LIMITED",
"retryable": true,
"retry_after_seconds": 30
}
แฟล็ก retryable ที่ชัดเจนช่วยให้คุณสามารถแทนที่ค่าเริ่มต้นเมื่อจำเป็น เช่น การตั้งค่า subcode 500 เฉพาะให้เป็นแบบสิ้นสุด เนื่องจากการลองใหม่จะทำให้สถานะเสียหาย ทำเอกสารประกอบแฟล็กนี้เพียงครั้งเดียวและ SDK ไคลเอนต์ทุกตัวที่คุณเผยแพร่จะได้รับพฤติกรรมการถอยกลับที่สม่ำเสมอ
Correlation ID และการกำหนดเวอร์ชันสัญญาข้อผิดพลาด
การตัดสินใจเล็กๆ อีกสองเรื่องที่เหลือจะช่วยให้สัญญาเสร็จสมบูรณ์ และทั้งสองเรื่องนี้ตอนนี้อาจดูไม่สำคัญ แต่ในภายหลังอาจมีค่าใช้จ่ายสูง
ให้ ID แก่ทุกคำขอ ยอมรับส่วนหัว X-Request-Id ที่เข้ามา (หรือสร้างขึ้นมาเอง) ประทับ ID นั้นในทุกบรรทัดของบันทึก และสะท้อนกลับในเนื้อหาข้อผิดพลาดทุกส่วนเป็น request_id เมื่อลูกค้าวางข้อผิดพลาดลงในตั๋วสนับสนุน ฟิลด์เดียวนี้จะเปลี่ยนการค้นหาบันทึกเป็นชั่วโมงให้เป็นการค้นหาเดียว ในการตั้งค่าแบบกระจาย ให้ส่ง traceparent ของ W3C ไปพร้อมกัน เพื่อให้ ID ติดตามคำขอข้ามบริการ
กำหนดเวอร์ชันสัญญาข้อผิดพลาดของคุณเหมือนกับตัว API เอง การเพิ่มส่วนขยายใหม่หรือโค้ดข้อผิดพลาดใหม่นั้นปลอดภัย การเปลี่ยนชื่อ errors[].field การเปลี่ยนความหมายของโค้ด หรือการย้ายจากรูปแบบเฉพาะกิจไปเป็น Problem Details เป็นการเปลี่ยนแปลงที่ส่งผลกระทบ และจะส่งผลกระทบต่อเส้นทางโค้ดที่ทีมทดสอบน้อยที่สุด URI ของ type ให้กลไกที่ชัดเจนแก่คุณ: รักษา URI ของประเภทเดิมให้เสถียรตลอดไป แนะนำ URI ใหม่สำหรับความหมายใหม่ และระบุในเอกสารประกอบของคุณว่าส่วนขยายที่ไม่รู้จักและโค้ดที่ไม่รู้จักจะต้องถูกละเลย ไม่ถือว่าเป็นความล้มเหลว ข้อกำหนดความเข้ากันได้แบบส่งต่อนี้คือสิ่งที่ช่วยให้คุณพัฒนาได้โดยไม่ต้องมี v2
ทดสอบเส้นทางข้อผิดพลาดทุกเส้นทางใน Apidog
นี่คือความจริงที่อึดอัด: สัญญาข้อผิดพลาดเสื่อมโทรมเพราะไม่มีอะไรใช้งานมัน เส้นทางที่ปกติทำงานได้ดีจะถูกนำเสนอในการสาธิตทุกครั้ง; ส่วน 422 จะทำงานเมื่อลูกค้าพบปัญหา การแก้ไขคือการทำให้กรณีความล้มเหลวเป็นสิ่งสำคัญลำดับแรกในชุดการทดสอบของคุณ และนี่คือที่ที่ Apidog ได้รับความสำคัญในเวิร์กโฟลว์
สองคุณสมบัติที่เกี่ยวข้องโดยตรงกับปัญหานี้
สถานการณ์การทดสอบสำหรับฝั่งเซิร์ฟเวอร์ สำหรับแต่ละ endpoint ให้สร้างสถานการณ์สำหรับแต่ละกรณีความล้มเหลว: การรับรองความถูกต้องหายไปคาดว่าจะได้ 401, บทบาทไม่เพียงพอคาดว่าจะได้ 403, จำนวนเงินติดลบคาดว่าจะได้ 422 พร้อม errors[0].code เท่ากับ AMOUNT_NOT_POSITIVE, ทราฟฟิกพุ่งสูงขึ้นคาดว่าจะได้ 429 พร้อมส่วนหัว Retry-After การยืนยันด้วยภาพของ Apidog ตรวจสอบสถานะ ส่วนหัว และฟิลด์เนื้อหาโดยไม่ต้องเขียนสคริปต์ และคุณสามารถตรวจสอบ payload ทั้งหมดเทียบกับ Problem Details JSON Schema ของคุณ เพื่อให้ความคลาดเคลื่อนใดๆ ในรูปแบบข้อผิดพลาดส่งผลให้ CI ล้มเหลว ไม่ใช่ใน Production คู่มือการยืนยัน API ของเราแสดงรูปแบบการยืนยันโดยละเอียด
Mock server สำหรับฝั่งไคลเอนต์ ทีมส่วนหน้าและ SDK ของคุณจำเป็นต้องสร้างตามการตอบกลับ 4xx และ 5xx ก่อนที่แบ็กเอนด์จะสามารถสร้างได้ตามต้องการ Apidog mock servers ส่งคืนเนื้อหา Problem Details ที่ตรงจากข้อมูลจำเพาะ API ของคุณ ดังนั้นคุณสามารถจำลอง 503 ด้วย Retry-After: 120, 409 เมื่อส่งซ้ำสองครั้ง, หรือ payload การตรวจสอบความถูกต้อง errors[] เต็มรูปแบบ จากนั้นดูว่าไคลเอนต์แสดงผลและลองใหม่อย่างไร ไม่ต้องสร้าง Express stub ด้วยมือ ไม่ต้องคอมเมนต์โค้ดแบ็กเอนด์เพื่อบังคับให้เกิดความล้มเหลว
ออกแบบสัญญาข้อผิดพลาด เข้ารหัสเป็นสถานการณ์จำลองและ mock และเชื่อมโยงทั้งสองเข้ากับ CI ดาวน์โหลด Apidog และทดลองใช้ฟรี; การนำเข้าข้อมูลจำเพาะ OpenAPI ที่มีอยู่จะทำให้คุณได้รับ mockable error responses ได้ภายในไม่กี่นาที
คำถามที่พบบ่อย
ฉันควรใช้ 400 หรือ 422 สำหรับข้อผิดพลาดในการตรวจสอบความถูกต้อง?
ใช้ 400 เมื่อคำขอผิดรูปแบบและเซิร์ฟเวอร์ไม่สามารถทำความเข้าใจได้: JSON ไม่ถูกต้อง, ประเภทเนื้อหาผิด, ฟิลด์ที่จำเป็นหายไป ใช้ 422 เมื่อคำขอถูกแยกวิเคราะห์อย่างถูกต้องแต่ค่าที่ส่งมาขัดต่อกฎของโดเมนของคุณ เช่น จำนวนเงินติดลบหรือสกุลเงินที่ไม่รองรับ ประโยชน์ในทางปฏิบัติคือการวินิจฉัย: 422 บอกไคลเอนต์ว่า “แก้ไขข้อมูลของคุณ” ในขณะที่ 400 บอกว่า “แก้ไขรูปแบบคำขอของคุณ” ไม่ว่าจะเลือกใช้แบบไหน ให้ใช้ให้สอดคล้องกันในทุกๆ จุดสิ้นสุด
application/problem+json คืออะไร?
เป็นประเภทสื่อที่กำหนดโดย RFC 9457 สำหรับ Problem Details ซึ่งเป็นรูปแบบข้อผิดพลาด JSON มาตรฐานสำหรับ HTTP API การตอบกลับที่มีประเภทเนื้อหานี้จะมีสมาชิก type, title, status, detail และ instance รวมถึงส่วนขยายใดๆ ที่คุณกำหนด เช่น อาร์เรย์ errors[] สำหรับข้อผิดพลาดในการตรวจสอบความถูกต้องระดับฟิลด์ การใช้ประเภทสื่อที่ลงทะเบียนนี้ทำให้ไคลเอนต์ทั่วไปและมิดเดิลแวร์สามารถจดจำข้อผิดพลาดของคุณได้โดยไม่ต้องกำหนดค่าเพิ่มเติม คำอธิบาย RFC 9457 ของเรา ครอบคลุมข้อมูลจำเพาะฉบับเต็ม
ไคลเอนต์ควรรองรับการลองใหม่โดยอัตโนมัติสำหรับข้อผิดพลาด HTTP ใดบ้าง?
ลองใหม่ 429, 502, 503 และ 504 ด้วย exponential backoff และ jitter โดยเคารพ Retry-After หากมี ให้พิจารณา 500 ว่าควรลองใหม่อย่างระมัดระวังหนึ่งครั้ง อย่าลองใหม่การตอบกลับ 4xx อื่นๆ เพราะคำขอจะล้มเหลวในลักษณะเดิมทุกครั้ง สำหรับ endpoints ที่เปลี่ยนแปลงข้อมูล ให้จับคู่การลองใหม่กับ idempotency keys เพื่อไม่ให้คำขอที่เล่นซ้ำมีการเรียกเก็บเงินซ้ำหรือสร้างซ้ำ
ฉันจะทดสอบการตอบกลับข้อผิดพลาดของ API โดยไม่ทำให้แบ็กเอนด์ของฉันเสียหายได้อย่างไร?
จำลองสถานการณ์เหล่านั้น ชี้ไคลเอนต์ของคุณไปยัง Apidog mock server ที่ส่งคืนเนื้อหา 4xx และ 5xx ที่ตรงตามข้อมูลจำเพาะของคุณ จากนั้นตรวจสอบการแสดงผลและพฤติกรรมการลองใหม่สำหรับแต่ละรายการ ทางฝั่งเซิร์ฟเวอร์ ให้เขียนสถานการณ์การทดสอบที่ส่ง payload ที่ไม่ถูกต้อง, การยืนยันตัวตนที่ขาดหายไป และทราฟฟิกที่พุ่งสูงขึ้น จากนั้นยืนยันสถานะโค้ด, ส่วนหัว และ schema ของเนื้อหาข้อผิดพลาด ทั้งสองส่วนจะทำงานใน CI เพื่อให้สัญญาข้อผิดพลาดมีความถูกต้องโดยไม่ต้องมีใครบังคับให้เกิดความล้มเหลวด้วยตนเอง
