RESTful API Design: HTTP Methods, Status Code, Endpoint Naming
RESTful API คือแนวทางออกแบบ API โดยมองข้อมูลเป็น Resource ใช้ HTTP Methods เพื่อระบุการกระทำ และใช้ Status Code เพื่อบอกผลลัพธ์อย่างเป็นมาตรฐาน
Timeline/ประวัติศาสตร์
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart LR
subgraph Era1["ยุค RPC / Action Endpoint"]
A["/getUser /createUser
ตั้งชื่อตาม action"]
end
subgraph Era2["ยุค REST / Resource Endpoint"]
B["/users /users/:id
ตั้งชื่อตาม resource"]
C["HTTP Methods
GET POST PUT DELETE"]
end
subgraph Era3["ยุค API Contract / Documentation"]
D["OpenAPI/Swagger
เอกสารมาตรฐาน"]
E["Versioning
/api/v1"]
end
A --> B --> C --> D --> E
หลักการ REST
- Stateless Server ไม่เก็บ session state ของ request ก่อนหน้า
- Client-Server แยกหน้าที่ระหว่าง Client กับ Server
- Uniform Interface ใช้รูปแบบ endpoint และ method ที่คาดเดาได้
- Resource Naming ใช้
/users สำหรับ Collection และ /users/:id สำหรับ Single Resource
- HTTP Methods ได้แก่ GET, POST, PUT/PATCH, DELETE
- Status Codes เช่น 200, 201, 204, 400, 401, 403, 404, 409, 422, 500
- JSON Format เป็นรูปแบบ Request/Response Body ที่ใช้บ่อย
- Versioning เช่น
/api/v1/users
- Swagger/OpenAPI ใช้ทำเอกสาร API เบื้องต้น
ตาราง HTTP Methods
| Method |
ความหมาย |
Endpoint ตัวอย่าง |
Status สำเร็จ |
| GET |
อ่านข้อมูล |
GET /api/v1/users |
200 |
| POST |
สร้างข้อมูล |
POST /api/v1/users |
201 |
| PUT |
แก้ไขทั้ง resource |
PUT /api/v1/users/1 |
200 |
| PATCH |
แก้ไขบางส่วน |
PATCH /api/v1/users/1 |
200 |
| DELETE |
ลบข้อมูล |
DELETE /api/v1/users/1 |
204 |
ตาราง Status Codes
| Code |
ความหมาย |
ใช้เมื่อใด |
| 200 |
OK |
ดึงหรือแก้ไขสำเร็จ |
| 201 |
Created |
สร้าง resource สำเร็จ |
| 204 |
No Content |
ลบสำเร็จและไม่มี body |
| 400 |
Bad Request |
request ไม่ถูกต้อง |
| 401 |
Unauthorized |
ยังไม่ยืนยันตัวตน |
| 403 |
Forbidden |
ไม่มีสิทธิ์ |
| 404 |
Not Found |
ไม่พบ resource |
| 409 |
Conflict |
ข้อมูลชนกัน |
| 422 |
Unprocessable Entity |
validation ไม่ผ่าน |
| 500 |
Server Error |
error ฝั่ง server |
Mermaid Diagram: REST Resource Design
%%{init: {"theme": "base", "themeVariables": {"primaryColor": "#fabd2f", "primaryTextColor": "#282828", "primaryBorderColor": "#b57614", "lineColor": "#7c6f64", "secondaryColor": "#83a598", "tertiaryColor": "#b8bb26", "background": "#fbf1c7", "mainBkg": "#ebdbb2", "fontFamily": "Tahoma, sans-serif"}}}%%
flowchart TD
A["Resource
users"] --> B["Collection
/api/v1/users"]
A --> C["Single Resource
/api/v1/users/:id"]
B --> D["GET
อ่านหลายรายการ"]
B --> E["POST
สร้างรายการ"]
C --> F["GET/PUT/PATCH
อ่านหรือแก้ไข"]
C --> G["DELETE
ลบรายการ"]
Code Example
// restful-routes.mjs
// ตัวอย่าง route naming และ status code ตาม REST
import express from 'express';
const app = express();
app.use(express.json());
let users = [{ id: 1, name: 'Ada' }];
app.get('/api/v1/users', (req, res) => {
res.status(200).json({ data: users });
});
app.post('/api/v1/users', (req, res) => {
if (!req.body.name) {
return res.status(422).json({ message: 'name is required' });
}
const user = { id: Date.now(), name: req.body.name };
users.push(user);
res.status(201).json({ data: user });
});
app.delete('/api/v1/users/:id', (req, res) => {
users = users.filter(user => user.id !== Number(req.params.id));
res.status(204).send();
});
app.listen(3000, () => console.log('REST API on http://localhost:3000'));
// ตัวอย่างการใช้งาน:
// GET /api/v1/users
// POST /api/v1/users body: { "name": "Grace" }
// DELETE /api/v1/users/1
กิจกรรมท้ายบท
- ออกแบบ API สำหรับระบบบทเรียน
- ระบุ endpoint, method, request body และ response body
- เขียน status code ที่ควรใช้ในแต่ละกรณี
- ร่างเอกสาร API แบบ Swagger/OpenAPI อย่างง่าย
กลับสัปดาห์ที่ 10