0
0
Lập trình
Admin Team
Admin Teamtechmely

Thực Hành Tốt Nhất Về Định Dạng JSON Phản Hồi API

Đăng vào 7 tháng trước

• 4 phút đọc

Giới Thiệu

Khi chúng ta nói về việc xây dựng API, thường thì trọng tâm sẽ nằm ở các endpointtính năng. Tuy nhiên, một phần rất quan trọng là phản hồi API thường bị xem nhẹ. Nếu định dạng phản hồi không hợp lý, điều này có thể gây khó khăn cho frontend, làm cho việc gỡ lỗi trở nên phức tạp và tiêu tốn băng thông hơn cần thiết.

Trong bài viết này, chúng ta sẽ khám phá cách thức xây dựng định dạng phản hồi API lý tưởng: ngắn gọn, nhất quán, dễ dàng theo dõi và thân thiện với frontend.


Tại Sao Định Dạng Phản Hồi API Quan Trọng?

  1. Tính Nhất Quán → Frontend không cần phải tạo ra hàng ngàn điều kiện đặc biệt để phân tích JSON.
  2. Hiệu Quả → Không lãng phí băng thông với các trường dữ liệu dư thừa.
  3. Dễ Gỡ Lỗi → Có request_id để theo dõi trong log backend một cách nhanh chóng.
  4. Hỗ Trợ Đa Ngôn Ngữ → Mã lỗi tiêu chuẩn có thể được dịch sang ngôn ngữ của người dùng từ phía frontend.

Tóm lại, việc này giúp cuộc sống của các lập trình viên frontend trở nên dễ dàng hơn và giúp lập trình viên backend dễ dàng hơn trong việc theo dõi lỗi. Đó là một sự thắng lợi cho cả hai bên!


Nguyên Tắc Cơ Bản Của Định Dạng Phản Hồi

Có một số nguyên tắc mà chúng ta nên tuân theo:

  • Mã trạng thái HTTP được sử dụng để chỉ trạng thái chính (200, 400, 401, 404, 500, v.v.).
  • Nội dung phản hồi tập trung vào nội dung → data nếu thành công, error nếu thất bại.
  • Luôn có request_id để theo dõi.
  • Lỗi sử dụng mã tiêu chuẩn → Phía frontend sẽ xác định thông điệp thân thiện với người dùng.

Ví Dụ Về Định Dạng Phản Hồi Nhất Quán

✅ Phản Hồi Thành Công – Tài Nguyên Đơn

json Copy
{
  "request_id": "uuid",
  "data": {
    "id": 123,
    "name": "Nandan",
    "email": "nandan@example.com"
  }
}

✅ Phản Hồi Thành Công – Danh Sách + Phân Trang

json Copy
{
  "request_id": "uuid",
  "items": [
    { "id": 1, "title": "Mục Đầu Tiên" },
    { "id": 2, "title": "Mục Thứ Hai" }
  ],
  "meta": {
    "page": 1,
    "per_page": 10,
    "total": 25
  }
}

❌ Lỗi Xác Thực (400/422)

json Copy
{
  "request_id": "uuid",
  "error": {
    "message": "Lỗi Xác Thực Payload",
    "code": "VALIDATION_ERROR",
    "fields": {
      "email": ["BẮT BUỘC", "ĐỊNH DẠNG KHÔNG HỢP LỆ", "DUY NHẤT"],
      "password": ["BẮT BUỘC", "ĐỘ DÀI TỐI THIỂU"]
    }
  }
}

❌ Lỗi Không Được Phép (401)

json Copy
{
  "request_id": "uuid",
  "error": {
    "message": "Không Được Phép",
    "code": "UNAUTHORIZED"
  }
}

❌ Lỗi Không Tìm Thấy (404)

json Copy
{
  "request_id": "uuid",
  "error": {
    "message": "Tài Nguyên Không Tìm Thấy",
    "code": "NOT_FOUND"
  }
}

❌ Lỗi Lỗi Máy Chủ (500)

json Copy
{
  "request_id": "uuid",
  "error": {
    "message": "Lỗi Máy Chủ Nội Bộ",
    "code": "INTERNAL_ERROR"
  }
}

Danh Sách Mã Lỗi Tiêu Chuẩn

Để đảm bảo tính nhất quán, backend cần sử dụng các mã lỗi rõ ràng. Frontend chỉ cần ánh xạ mã này với thông điệp phù hợp với ngôn ngữ.

🔹 Xác Thực

  • REQUIRED → trường dữ liệu trống nhưng bắt buộc
  • INVALID_TYPE → kiểu dữ liệu sai
  • INVALID_FORMAT → định dạng sai (ví dụ: email không hợp lệ)
  • MIN_LENGTH / MAX_LENGTH → chiều dài chuỗi không phù hợp
  • MIN_VALUE / MAX_VALUE → số không phù hợp với giới hạn
  • UNIQUE → dữ liệu đã tồn tại (ví dụ: email đã được sử dụng)
  • ENUM_VALUE → giá trị không hợp lệ
  • MISMATCH → xác nhận không khớp (ví dụ: password & confirm_password)

🔹 Bảo Mật & Xác Thực

  • UNAUTHORIZED → chưa đăng nhập / token không có
  • INVALID_TOKEN → token hết hạn hoặc sai
  • FORBIDDEN_ACTION → người dùng không có quyền
  • ACCOUNT_LOCKED → tài khoản bị khóa
  • TOO_MANY_REQUESTS → giới hạn tỷ lệ đạt

🔹 Máy Chủ

  • INTERNAL_ERROR → lỗi không mong đợi
  • SERVICE_UNAVAILABLE → dịch vụ phụ thuộc không khả dụng
  • TIMEOUT → thời gian chờ yêu cầu
  • CONFLICT → xung đột tài nguyên

Tại Sao Không Cần Thêm Trường Như resource?

Đơn giản là: nếu chúng ta yêu cầu tới /users/123 và phản hồi là 404 NOT_FOUND, đã rõ tài nguyên mà chúng ta đang nói tới là user. Việc thêm "resource": "user" vào body có thể tạo ra sự không nhất quán vì không phải tất cả các lỗi đều cần trường này. Do đó, chúng ta nên tối thiểu hóa và duy trì tính nhất quán.


Kết Luận

Định dạng phản hồi API lý tưởng là:

  • Thành Côngdata hoặc items + meta.
  • Lỗi → luôn có error.message + error.code (và fields nếu có lỗi xác thực).
  • Luôn có request_id.
  • Frontend sẽ dịch mã lỗi, không phải backend.

Với định dạng này:

  • Backend nhẹ nhàng hơn và tiết kiệm băng thông.
  • Frontend linh hoạt hơn và có thể hỗ trợ đa ngôn ngữ.
  • Gỡ lỗi dễ dàng hơn nhờ có request_id.

👉 Vì vậy, trước khi nghĩ đến việc triển khai microservices hay mở rộng phức tạp, hãy đảm bảo rằng API của bạn có phản hồi nhất quán, gọn gàng và thân thiện với lập trình viên. Tin tôi đi, điều này sẽ tiết kiệm rất nhiều thời gian và công sức cho đội ngũ trong tương lai.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào