การใช้ JSON ใน REST API: แนวทางปฏิบัติที่ดีที่สุด
JSON ใน REST API
JSON และ REST API เป็นคู่ที่ลงตัวกันอย่างยิ่ง ไวยากรณ์ที่เบาของ JSON, การรองรับ array แบบ native และการสนับสนุนภาษาแบบสากลทำให้เป็นรูปแบบปริยายสำหรับ Web API สมัยใหม่ แต่การใช้ JSON ใน API ของคุณเพียงอย่างเดียวนั้นไม่เพียงพอ -- การปฏิบัติตามแบบแผนและแนวทางปฏิบัติที่ดีที่สุดที่เป็นที่ยอมรับทำให้ API ของคุณสอดคล้องกัน ใช้งานง่าย และผสานรวมได้ง่าย
รูปแบบ Request และ Response
โครงสร้าง Envelope ที่สอดคล้องกัน
ใช้ JSON envelope ที่สอดคล้องกันสำหรับการตอบกลับ API ทั้งหมด สิ่งนี้ทำให้การประมวลผลทางฝั่งไคลเอนต์คาดเดาได้และลดความซับซ้อนในการจัดการข้อผิดพลาด
{
"status": "success",
"data": {
"user": {
"id": 123,
"name": "Alice",
"email": "alice@example.com"
}
},
"meta": {
"requestId": "req-a1b2c3d4",
"timestamp": "2026-07-19T10:30:00Z"
}
}
Snake Case กับ Camel Case
เลือกแบบแผนการตั้งชื่อแบบหนึ่งและใช้อย่างสม่ำเสมอทั่วทั้ง API ของคุณ:
- Camel Case (
createdAt,firstName): พบบ่อยในระบบนิเวศ JavaScript/TypeScript - Snake Case (
created_at,first_name): พบบ่อยในระบบนิเวศ Python, Ruby และ PHP
ไม่ว่าคุณจะเลือกแบบไหน จัดทำเอกสารให้ชัดเจนและพิจารณาใช้ transformation layer หากภาษา backend ของคุณใช้แบบแผนที่แตกต่าง
HTTP Status Codes กับ JSON
HTTP status codes ที่เหมาะสมเสริมการตอบกลับ JSON ของคุณ ใช้อย่างสอดคล้องกัน:
| Status Code | Meaning | When to Use |
|-------------|---------|-------------|
| 200 OK | Success | GET, PUT, PATCH success |
| 201 Created | Resource created | POST success |
| 204 No Content | Deletion success | DELETE success (no JSON body) |
| 400 Bad Request | Invalid JSON syntax | Malformed request body |
| 401 Unauthorized | Authentication required | Missing or invalid token |
| 403 Forbidden | Insufficient permissions | Valid auth but not allowed |
| 404 Not Found | Resource doesn't exist | Invalid ID or path |
| 422 Unprocessable Entity | Validation failure | Semantic errors in valid JSON |
| 429 Too Many Requests | Rate limit hit | Client exceeding limits |
| 500 Internal Server Error | Server-side failure | Unexpected errors |
รูปแบบการตอบกลับข้อผิดพลาดมาตรฐาน
{
"status": "error",
"error": {
"code": "VALIDATION_ERROR",
"message": "The request body contains invalid fields",
"details": [
{
"field": "email",
"message": "Must be a valid email address",
"code": "INVALID_FORMAT"
},
{
"field": "age",
"message": "Must be a positive integer",
"code": "OUT_OF_RANGE"
}
]
}
}
ทรัพยากรแบบซ้อน (Nested Resources)
การแสดงความสัมพันธ์
REST API จำเป็นต้องแสดงทรัพยากรที่เกี่ยวข้องบ่อยครั้ง นี่คือรูปแบบทั่วไป:
แบบฝัง (Embedded / eager loading):
{
"order": {
"id": 5001,
"total": 29.99,
"customer": {
"id": 123,
"name": "Alice",
"email": "alice@example.com"
},
"items": [
{
"productId": 42,
"name": "Widget",
"quantity": 2,
"price": 14.99
}
]
}
}
แบบอ้างอิง (Referenced / lazy loading) -- ใช้ IDs และให้ endpoints แยกต่างหาก:
{
"order": {
"id": 5001,
"total": 29.99,
"customerId": 123,
"itemIds": [101, 102]
}
}
กฎทั่วไป: ฝังข้อมูลที่เกี่ยวข้องที่จำเป็นต้องใช้ร่วมกันเสมอ อ้างอิงข้อมูลที่ถูกดึงตามเงื่อนไขหรือในเวลาที่แตกต่างกัน
รูปแบบการแบ่งหน้า (Pagination)
เมื่อส่งคืนรายการทรัพยากร การแบ่งหน้าเป็นสิ่งจำเป็น ใช้รูปแบบการแบ่งหน้าที่สอดคล้องกัน:
Offset-Based Pagination
{
"status": "success",
"data": [
{ "id": 1, "name": "User 1" },
{ "id": 2, "name": "User 2" }
],
"pagination": {
"page": 1,
"perPage": 20,
"totalItems": 156,
"totalPages": 8,
"links": {
"first": "/api/users?page=1&perPage=20",
"prev": null,
"next": "/api/users?page=2&perPage=20",
"last": "/api/users?page=8&perPage=20"
}
}
}
Cursor-Based Pagination (แนะนำสำหรับชุดข้อมูลขนาดใหญ่)
{
"status": "success",
"data": [
{ "id": 100, "name": "User 100" },
{ "id": 101, "name": "User 101" }
],
"pagination": {
"nextCursor": "eyJpZCI6MTAxfQ==",
"hasMore": true
}
}
การแบ่งหน้าแบบ cursor มีความน่าเชื่อถือมากกว่าสำหรับข้อมูลเรียลไทม์ที่ระเบียนใหม่อาจเลื่อนขอบเขตของหน้า
JSON ใน API Requests
POST / PUT Request Bodies
รับ JSON ด้วย header Content-Type: application/json:
{
"title": "New Blog Post",
"content": "This is the content...",
"tags": ["json", "rest-api"],
"published": false
}
การอัปเดตบางส่วนด้วย PATCH
ใช้ PATCH สำหรับการอัปเดตบางส่วน รับเฉพาะฟิลด์ที่ควรเปลี่ยนแปลง:
// PATCH /api/users/123
{
"email": "newemail@example.com"
}
การกรอง การเรียงลำดับ และการค้นหา
ใช้ query parameters สำหรับการจัดการข้อมูล โดยรักษา JSON body ให้สะอาด:
GET /api/users?filter[role]=admin&sort=-createdAt&search=alice
{
"status": "success",
"data": [ /* filtered, sorted results */ ]
}
การจำกัดอัตรา (Rate Limiting)
รวมข้อมูลการจำกัดอัตราใน response headers และเป็นทางเลือกใน JSON body:
{
"status": "error",
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please try again later."
},
"meta": {
"rateLimit": {
"limit": 100,
"remaining": 0,
"resetAt": "2026-07-19T11:00:00Z"
}
}
}
รายการตรวจสอบแนวทางปฏิบัติที่ดีที่สุดของ JSON
- [ ] ใช้การตั้งชื่อคีย์ที่สอดคล้องกัน (camelCase หรือ snake_case ตลอดทั้งโครงการ)
- [ ] ส่งคืน HTTP status codes ที่เหมาะสมกับทุกการตอบกลับ
- [ ] รวมรูปแบบข้อผิดพลาดที่สอดคล้องกันพร้อมรหัสข้อผิดพลาดที่เครื่องอ่านได้
- [ ] แบ่งหน้า list endpoints ด้วย pagination object ที่เป็นมาตรฐาน
- [ ] ใช้ JSON Schema เพื่อจัดทำเอกสารและตรวจสอบโครงสร้าง request/response
- [ ] ตั้งค่า
Content-Type: application/jsonบน JSON endpoints ทั้งหมด - [ ] บีบอัดการตอบกลับ JSON ด้วย gzip หรือ brotli ในการผลิต
- [ ] บังคับใช้ขีดจำกัดขนาด payload สูงสุด (เช่น 1MB เป็นค่าปริยาย)
- [ ] ใช้ HTTPS เพื่อเข้ารหัสข้อมูล JSON ระหว่างการส่ง
- [ ] จัดโครงสร้างรายละเอียดข้อผิดพลาดเพื่อช่วยให้ไคลเอนต์ดีบักโดยไม่เปิดเผยข้อมูลภายใน
การตรวจสอบ JSON ของ API ของคุณ
รันการตอบกลับ API ของคุณผ่าน JSON validator เพื่อตรวจจับข้อผิดพลาดการจัดรูปแบบก่อนถึงไคลเอนต์ การตอบกลับ JSON ที่สอดคล้องและถูกต้องทำให้ API ของคุณน่าเชื่อถือและเป็นมิตรกับนักพัฒนา ใช้เครื่องมือ JSON Formatter & Validator ของเราเพื่อทดสอบ payloads ของคุณระหว่างการพัฒนา