1. REST API là gì?
REST (Representational State Transfer) là một kiến trúc thiết kế API cho phép các ứng dụng client (Mobile App, Web App, Desktop App) giao tiếp với server thông qua HTTP protocol.
Đặc điểm chính:
Stateless: Server không lưu trạng thái của client, mỗi request độc lập Client-Server: Tách biệt client và server, chỉ giao tiếp qua API Data-only: API chỉ trả về dữ liệu (JSON, XML), KHÔNG trả về HTML/UI Resource-based: Mọi thứ đều là “resource” (users, posts, products…) Ví dụ:
Traditional Web App (Server-side rendering):
Browser → GET /products → Server renders HTML → Browser hiển thị
REST API (Client-side rendering):
Mobile App → GET /api/products → Server trả JSON → App render UI
Web App → GET /api/products → Server trả JSON → React/Vue render UI
2. Phân loại API Clients
App Backend API
Mục đích: Phục vụ ứng dụng của chính mình (Mobile App, SPA, Web App)
Đặc điểm:
Private API - chỉ app của bạn sử dụng Có authentication chặt chẽ (JWT, OAuth) Tùy chỉnh theo nhu cầu app Có thể thay đổi structure nếu cần Ví dụ:
Service API (Public/Third-party API)
Mục đích: Cung cấp dịch vụ cho bên thứ 3, nhiều apps khác nhau
Đặc điểm:
Cần API key/token để access Phải đảm bảo backward compatibility Documentation rất quan trọng Rate limiting (giới hạn số requests) Ví dụ:
So sánh:
3. Các loại dữ liệu API trả về
3.1. JSON (JavaScript Object Notation)
Ưu điểm:
✅ Chuẩn chung hiện nay (99% APIs dùng JSON) ✅ Lightweight, nhẹ hơn XML ✅ Native support trong JavaScript ✅ Hỗ trợ tốt mọi ngôn ngữ lập trình Nhược điểm:
❌ Không có schema validation built-in (cần dùng JSON Schema) Ví dụ:
3.2. XML (eXtensible Markup Language)
Ưu điểm:
✅ Có schema validation (XSD) ✅ Phù hợp với enterprise systems cũ Nhược điểm:
❌ Ít được dùng trong modern APIs Ví dụ:
Khi nào dùng XML:
Legacy systems (SOAP APIs) Banking, Insurance, Government systems 3.3. HTML
Ưu điểm:
✅ Render trực tiếp trên browser Nhược điểm:
❌ KHÔNG phải REST API! (REST API chỉ trả data) ❌ Không phù hợp cho Mobile Apps ❌ Client không thể custom UI Ví dụ (KHÔNG phải REST):
Lưu ý: Nếu API trả HTML → Đó là Server-Side Rendering, KHÔNG phải REST API!
3.4. Plain Text
Ưu điểm:
Nhược điểm:
❌ Không phù hợp cho complex data Ví dụ:
Khi nào dùng Plain Text:
Health check endpoints: GET /health → OK Simple status: GET /api/status → running Chuẩn chung hiện nay: JSON
JSON là chuẩn de facto cho REST APIs vì:
Balance giữa human-readable và machine-readable Content-Type headers:
4. Các loại HTTP Methods
GET - Lấy dữ liệu
Đặc điểm:
Idempotent (gọi nhiều lần, kết quả giống nhau) Safe (không thay đổi data) POST - Tạo mới resource
Đặc điểm:
NOT idempotent (gọi nhiều lần → tạo nhiều records) Response thường là 201 Created PUT - Thay thế toàn bộ resource
Đặc điểm:
Nếu resource không tồn tại → tạo mới PATCH - Update một phần resource
Đặc điểm:
Chỉ gửi fields cần update Phổ biến hơn PUT trong thực tế PUT vs PATCH:
DELETE - Xóa resource
Đặc điểm:
Idempotent (xóa 1 lần = xóa 100 lần) Response: 204 No Content hoặc 200 OK OPTIONS - Kiểm tra methods được phép
OPTIONS method cho phép client hỏi server về:
Methods nào được phép (GET, POST, PUT…)? Chính xác! Bạn hiểu đúng rồi. Để làm rõ hơn:
Lưu ý: OPTIONS Request là do Browser tự động gửi
Browser quyết định khi nào cần gửi OPTIONS preflight request dựa trên: Developer KHÔNG VIẾT CODE gửi OPTIONS - browser làm tự động!
OPTIONS to CORS Headers - Developer phải cấu hình
Developer phải cấu hình trên server để response OPTIONS request và các requests thật:
Flow hoàn chỉnh
Tóm tắt
Developer chỉ cần:
✅ Cấu hình CORS trên server (cors middleware hoặc manual) ❌ KHÔNG cần viết code gửi OPTIONS - browser tự làm ❌ KHÔNG cần viết code kiểm tra CORS - browser tự làm Ví dụ đơn giản nhất:
5. Cách đặt tên Endpoints (Best Practices)
✅ Đúng chuẩn REST
// Resources là danh từ số nhiều
GET /api/products // Lấy danh sách products
POST /api/products // Tạo product mới
GET /api/products/123 // Lấy product có id = 123
PUT /api/products/123 // Thay thế product 123
PATCH /api/products/123 // Update một phần product 123
DELETE /api/products/123 // Xóa product 123
// Nested resources
GET /api/users/456/orders // Orders của user 456
POST /api/users/456/orders // Tạo order cho user 456
GET /api/posts/789/comments // Comments của post 789
POST /api/posts/789/comments // Tạo comment cho post 789
// Actions/verbs chỉ khi thực sự cần
POST /api/auth/login
POST /api/auth/logout
POST /api/users/123/activate
POST /api/orders/456/cancel
POST /api/products/789/publish
❌ Sai chuẩn REST
// ❌ Dùng verbs trong URL
GET /api/getProducts
POST /api/createProduct
GET /api/deleteUser/123
// ✅ Đúng
GET /api/products
POST /api/products
DELETE /api/users/123
// ❌ Dùng số ít
GET /api/product/123
GET /api/user/456
// ✅ Đúng - luôn dùng số nhiều
GET /api/products/123
GET /api/users/456
URL Structure Best Practices
// Pattern: /api/{version}/{resource}/{id}/{sub-resource}
// Versioning
GET /api/v1/products
GET /api/v2/products // Breaking changes → new version
// Filtering
GET /api/products?category=phones&brand=apple
// Sorting
GET /api/products?sort=price_asc
GET /api/products?sort=-createdAt // "-" = descending
// Pagination
GET /api/products?page=2&limit=20
// Search
GET /api/products/search?q=iphone
// Fields selection
GET /api/products?fields=id,name,price
// Nested resources với limit
GET /api/users/123/posts?limit=5
6. Nguyên tắc của REST API (REST Principles)
1. Uniform Interface (Giao diện thống nhất)
Ý nghĩa: API endpoints phải rõ ràng, nhất quán, dễ dự đoán
Áp dụng:
Request/Response structure cũng phải consistent:
2. Stateless Interactions (Tương tác không trạng thái)
Ý nghĩa: Server KHÔNG lưu trạng thái của client, mỗi request phải chứa đủ thông tin
Ví dụ:
Lợi ích Stateless:
Scalable: Có thể thêm nhiều servers, request đến server nào cũng OK Reliable: Server crash không mất session Cacheable: Dễ cache responses Implement:
3. Cacheable (Có thể cache)
Ý nghĩa: Server nên set cache headers để client/proxy có thể cache responses
Áp dụng:
Cache strategies:
4. Client-Server Separation
Ý nghĩa: Client và Server độc lập, giao tiếp chỉ qua API
Lợi ích:
Client và Server develop độc lập Có thể swap Client (Web → Mobile) mà không đổi Server Có thể swap Server implementation mà không đổi Client Ví dụ:
5. Layered System (Hệ thống phân lớp)
Ý nghĩa: Client không cần biết có bao nhiêu layers giữa client và server
Ví dụ architecture:
Forward requests:
7. Response Status Code
// Success
200 OK - Request thành công (GET, PATCH, DELETE)
201 Created - Resource được tạo (POST)
204 No Content - Thành công nhưng không có data (DELETE)
// Client Errors
400 Bad Request - Request sai format
401 Unauthorized - Chưa đăng nhập
403 Forbidden - Đã login nhưng không có quyền
404 Not Found - Resource không tồn tại
422 Unprocessable - Validation failed
// Server Errors
500 Internal Server Error
503 Service Unavailable
Error Response Format
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Email is required",
"details": {
"field": "email",
"value": "",
"constraint": "required"
}
}
}
Complete Example
// routes/api/products.js
const router = require('express').Router();
// GET /api/products - List products
router.get('/', async (req, res) => {
try {
const { page = 1, limit = 20, category, sort } = req.query;
const products = await Product.findAll({
where: category ? { category } : {},
limit,
offset: (page - 1) * limit,
order: [[sort || 'createdAt', 'DESC']]
});
res.setHeader('Cache-Control', 'public, max-age=300');