ข้ามไปยังเนื้อหา

Validation Error

Validation error เป็น error ที่ API ส่งกลับบ่อยที่สุด และเป็นชนิดที่ client อยากแสดงผลให้สวยงามที่สุด validation response ที่ดีบอกผู้ใช้ได้อย่างชัดเจนว่า field ไหนผิดและเพราะอะไร — ทั้งหมดในคราวเดียว ไม่ใช่ทีละอันต่อหนึ่งรอบ

เมื่อ request parse ได้ถูกต้องแต่ค่าไม่ผ่านกฎของคุณ ให้ตอบ 422 Unprocessable Entity บางทีมใช้ 400 กับ client error ทั้งหมด ทั้งสองแนวมีเหตุผลรองรับ ขอแค่ใช้ให้สม่ำเสมอ และเก็บ 400 ไว้กับ request ที่ parse ไม่ออกตั้งแต่แรก

ขยาย Problem Details ด้วย array errors หนึ่งรายการต่อหนึ่ง field ที่มีปัญหา:

{
"type": "https://api.example.com/problems/validation",
"title": "Validation failed",
"status": 422,
"detail": "The request has 2 invalid fields.",
"errors": [
{ "field": "email", "message": "must be a valid email address" },
{ "field": "age", "message": "must be 18 or greater" }
]
}

ตรวจสอบทุก field และรวบรวมความล้มเหลวทั้งหมดก่อนตอบกลับ — อย่าหยุดที่ตัวแรก นี่สะท้อนวิธีที่ schema validator ทั่วไปทำงาน:

JavaScript

ในโปรเจกต์ TypeScript schema library (เช่น zod) ให้สิ่งนี้แก่คุณฟรี: parse input เทียบกับ schema และเมื่อล้มเหลวก็ map issue เหล่านั้นไปยัง array errors ของคุณ

ข้อดี (Validation Errors)ข้อแลกเปลี่ยน
client รู้ว่า field ไหนผิดและทำไม — UX ดีขึ้นvalidation logic ซ้ำกันระหว่าง client และ server
ป้องกัน invalid data เข้า databaseverbose error response สำหรับ form ที่มีหลาย field
400/422 ที่ชัดเจนทำให้ retry logic ถูกต้องvalidation rule บาง rule ต้อง query database (email unique)
machine-readable error ทำให้ client แสดง inline error ได้

Return Error เดียวสำหรับหลาย Field ที่ผิด อาการ:

  • form มี 5 field ผิด แต่ API return error ทีละ field
  • user แก้ field แรก submit ใหม่ → เห็น error ของ field ที่สอง → แก้ → submit ใหม่ …
  • validate ทุก field พร้อมกันแล้ว return errors array ครบทีเดียว

Validation Error vs Business Rule Error ปนกัน อาการ:

  • 400 Bad Request สำหรับทั้ง “email format ผิด” และ “email นี้ถูก suspend”
  • client ไม่รู้ว่าควรแสดง field error หรือ general error
  • แยก: 422 สำหรับ validation, 409 หรือ custom code สำหรับ business rule

💡 ตัวอย่างจากของจริง

Stripe API:

  • { "error": { "type": "invalid_request_error", "param": "amount", "message": "Amount must be greater than 0" } }
  • param บอก field ที่ผิด — client แสดง inline error ที่ field นั้นได้

GitHub API:

  • { "errors": [{ "resource": "Issue", "field": "title", "code": "missing_field" }, { "resource": "Issue", "field": "body", "code": "missing_field" }] }
  • ส่ง validation error ทุก field พร้อมกัน ไม่ใช่ทีละ field
input parse ได้ดีแต่มีสอง field ที่ละเมิดกฎทางธุรกิจ status ที่ดีที่สุดคือ?
ทำไมจึงส่ง validation error ทั้งหมดกลับในคราวเดียวแทนที่จะส่งแค่ตัวแรก?
อะไรที่ทำให้ validation error body แสดงผลได้ง่ายสำหรับ client?