REST API Design không chỉ là đặt vài endpoint rồi trả JSON. Với backend chạy production, API là hợp đồng giữa server, frontend, mobile app, đối tác tích hợp và cả các service nội bộ. Một API thiết kế kém sẽ làm client khó dùng, khó debug, khó versioning và rất dễ tạo technical debt.

Bài viết này là checklist thực tế để bạn thiết kế REST API rõ ràng, ổn định và dễ vận hành hơn trong backend production.

REST API Design là gì?

REST API Design là cách tổ chức endpoint, resource, method, response, error, authentication và quy tắc vận hành để API dễ hiểu, dễ tích hợp và bền vững khi hệ thống phát triển. Một REST API tốt thường có các đặc điểm:

  • URL phản ánh resource rõ ràng;
  • HTTP method đúng ý nghĩa;
  • status code nhất quán;
  • response schema dễ dự đoán;
  • error format thống nhất;
  • có pagination/filtering/sorting cho danh sách;
  • có cơ chế auth, rate limit và versioning phù hợp;
  • dễ log, monitor và debug khi production có lỗi.
Checklist REST API Design gồm resource URL, HTTP method, status code, response format, error format, auth, versioning và observability
REST API tốt cần rõ hợp đồng giữa backend và client, không chỉ trả JSON đúng.

Nếu bạn đang xây backend service mới, hãy xem API design như một phần của Backend Engineering, không phải chi tiết phụ.

1. Thiết kế resource và URL

REST API nên xoay quanh resource thay vì action. Resource là danh từ đại diện cho đối tượng hoặc tập hợp dữ liệu trong hệ thống.

Ví dụ tốt:

GET /users
GET /users/123
POST /users
PATCH /users/123
DELETE /users/123
GET /users/123/orders

Ví dụ nên tránh:

GET /getUser?id=123
POST /createUser
POST /updateUser
GET /listUserOrders

Một số nguyên tắc nên dùng:

  • Dùng danh từ số nhiều: /users, /orders, /articles.
  • Không đưa động từ CRUD vào URL nếu HTTP method đã thể hiện ý định.
  • Giữ nesting vừa đủ; tránh URL quá sâu như /companies/1/departments/2/teams/3/users/4.
  • Dùng slug hoặc ID nhất quán; nếu có cả hai, cần quy ước rõ.

2. Dùng HTTP method và status code đúng

HTTP method là phần quan trọng của API contract. Nếu dùng sai method, client sẽ khó hiểu API và các layer như cache, proxy, SDK cũng khó tối ưu.

Method Ý nghĩa thường dùng Ví dụ
GET Đọc dữ liệu, không thay đổi state GET /articles/abc
POST Tạo resource hoặc trigger action không idempotent POST /orders
PUT Thay thế toàn bộ resource PUT /users/123
PATCH Cập nhật một phần resource PATCH /users/123
DELETE Xóa resource DELETE /sessions/123

Status code cũng cần nhất quán:

  • 200 OK: request thành công và có body.
  • 201 Created: tạo resource thành công.
  • 204 No Content: thành công nhưng không cần body.
  • 400 Bad Request: request sai format hoặc thiếu field.
  • 401 Unauthorized: chưa xác thực hoặc token sai.
  • 403 Forbidden: đã xác thực nhưng không có quyền.
  • 404 Not Found: resource không tồn tại hoặc không được expose.
  • 409 Conflict: xung đột trạng thái, ví dụ duplicate hoặc concurrent update.
  • 422 Unprocessable Entity: validation fail ở cấp business rule.
  • 429 Too Many Requests: rate limit.
  • 500 Internal Server Error: lỗi server không mong muốn.

3. Chuẩn hóa request/response format

Client thích sự nhất quán. Nếu endpoint này trả data, endpoint khác trả trực tiếp object, endpoint khác nữa trả result, team sẽ mất nhiều thời gian xử lý case đặc biệt.

Một format phổ biến:

{
  "data": {
    "id": "123",
    "type": "article",
    "title": "REST API Design Checklist"
  },
  "meta": {
    "request_id": "req_abc123"
  }
}

Với danh sách:

{
  "data": [
    { "id": "1", "title": "Article A" },
    { "id": "2", "title": "Article B" }
  ],
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 125
  }
}

Checklist cho response:

  • Field naming thống nhất: snake_case hoặc camelCase, không trộn lẫn.
  • Datetime dùng ISO 8601, ví dụ 2026-05-21T13:00:00Z.
  • ID nên là string nếu có thể vượt giới hạn integer của client.
  • Không expose field nội bộ không cần thiết.
  • Không thay đổi kiểu dữ liệu của field đã public nếu không versioning.
Sơ đồ API contract gồm URL, method, request body, response body, error schema và versioning
API contract cần rõ URL, method, request, response, error và versioning.

4. Chuẩn hóa error format

Error format là nơi nhiều API production thất bại. Nếu lỗi không có structure ổn định, client khó hiển thị thông báo đúng, còn backend khó debug.

Một error response nên có:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Some fields are invalid.",
    "details": [
      { "field": "email", "message": "Email is already taken." }
    ],
    "request_id": "req_abc123"
  }
}

Nguyên tắc quan trọng:

  • message dành cho người dùng hoặc developer đọc nhanh.
  • code dành cho client xử lý logic.
  • request_id giúp trace log khi có lỗi production.
  • Không trả stack trace hoặc thông tin nhạy cảm ra public API.
  • Validation error nên chỉ rõ field và lý do.

5. Pagination, filtering và sorting

Mọi endpoint trả danh sách nên có pagination ngay từ đầu. Nếu ban đầu dữ liệu ít mà bỏ qua pagination, sau này API dễ chậm, response phình to và frontend phải sửa nhiều.

Ví dụ:

GET /articles?page=1&per_page=20
GET /articles?status=published&sort=-published_at
GET /articles?category=backend&q=api

Cần quy định rõ:

  • Giới hạn per_page tối đa, ví dụ 100.
  • Field nào được filter/sort.
  • Sort format: sort=published_at hay sort=-published_at.
  • Response có tổng số bản ghi hay dùng cursor pagination.
  • Với dữ liệu lớn hoặc feed realtime, cân nhắc cursor pagination thay vì offset.

6. Authentication, authorization và security

Authentication trả lời câu hỏi “bạn là ai?”, còn authorization trả lời “bạn được làm gì?”. Hai phần này không nên trộn lẫn.

Checklist security cơ bản:

  • Dùng HTTPS cho mọi request production.
  • Không gửi token qua query string; dùng header Authorization.
  • Phân quyền ở server, không tin logic ẩn/hiện nút trên frontend.
  • Validate input ở boundary.
  • Rate limit endpoint nhạy cảm như login, reset password, search.
  • Log sự kiện bảo mật quan trọng nhưng không log secret/token/password.

Nên đọc tiếp: Authentication và Authorization trong Backend.

7. Idempotency và versioning

Idempotency nghĩa là gọi cùng một request nhiều lần nhưng kết quả cuối cùng không bị lặp sai. Đây là điểm rất quan trọng với payment, order, webhook hoặc các request có retry.

Ví dụ: client gửi header:

Idempotency-Key: order_123_create_payment_001

Server lưu key này và đảm bảo nếu request bị retry, hệ thống không tạo hai payment cho cùng một order.

Versioning cũng cần được nghĩ sớm. Có nhiều cách:

  • URL versioning: /v1/articles
  • Header versioning: Accept: application/vnd.company.v1+json
  • Backward-compatible changes: thêm field mới nhưng không phá field cũ

Với đa số team sản phẩm, URL versioning đơn giản và dễ vận hành hơn. Nhưng dù chọn cách nào, cần có quy tắc deprecation rõ.

8. Observability và documentation

Một API production cần dễ debug. Khi client báo lỗi, backend team phải trả lời được:

  • Request nào lỗi?
  • User/service nào gọi?
  • Endpoint nào, status code nào?
  • Latency bao nhiêu?
  • Database/external API có lỗi không?
  • Release nào bắt đầu gây lỗi?

Tối thiểu nên có request ID, structured log, metrics theo endpoint, error rate, latency percentile và dashboard. Đây là phần nối trực tiếp với deploy backend lên production.

Checklist production readiness cho REST API gồm rate limit, logging, metrics, request id, documentation và backward compatibility
API production cần log, metrics, docs và backward compatibility, không chỉ cần endpoint chạy đúng.

Checklist REST API trước khi production

  • Resource URL rõ, dùng danh từ và nhất quán.
  • HTTP method đúng ý nghĩa.
  • Status code thống nhất giữa các endpoint.
  • Response format có cấu trúc dự đoán được.
  • Error format có code, message, details và request_id.
  • Endpoint danh sách có pagination và giới hạn per_page.
  • Filtering/sorting có whitelist field rõ ràng.
  • Authentication và authorization được kiểm ở server.
  • Endpoint nhạy cảm có rate limit.
  • Request tạo giao dịch quan trọng có idempotency key.
  • Có versioning hoặc backward-compatible policy.
  • Có API docs hoặc OpenAPI schema.
  • Có request ID, structured logging và metrics.
  • Có integration test cho happy path và error path chính.

FAQ

REST API có còn đáng học khi GraphQL/gRPC phổ biến hơn không?

Có. REST vẫn rất phổ biến cho public API, dashboard, mobile app và backend service thông thường. GraphQL/gRPC có lợi thế riêng, nhưng REST API Design vẫn là nền tảng quan trọng.

Nên dùng PUT hay PATCH?

Dùng PUT khi client gửi toàn bộ representation để thay thế resource. Dùng PATCH khi client chỉ cập nhật một số field. Trong sản phẩm thực tế, PATCH thường phổ biến hơn cho form update.

Có nên version API ngay từ đầu không?

Nên có chiến lược versioning ngay từ đầu, nhưng không nhất thiết phải tạo nhiều version sớm. Điều quan trọng là tránh breaking change tùy tiện và có quy tắc deprecate rõ.

Error message nên viết cho user hay developer?

Nên tách hai mục tiêu: message có thể thân thiện để hiển thị, còn coderequest_id phục vụ xử lý logic/debug. Không expose stack trace hoặc thông tin nhạy cảm.

Kết luận

REST API tốt là API dễ dùng, dễ debug và khó phá vỡ khi hệ thống lớn lên. Nếu bạn muốn phát triển năng lực backend nghiêm túc, hãy coi API design là một kỹ năng cốt lõi của Backend Engineering, ngang hàng với database, security, observability và deploy.

Nên đọc tiếp trong cụm Backend: