Skip to content

API Design: "Protocol đối thoại" FE-BE

Core

FE + BE đối thoại hiệu quả thế nào? Như: menu nhà hàng design sao khách nhìn hiểu? API design giải "rule đối thoại".


0. Câu hỏi: bạn từng gặp ác mộng này?

Scene 1: Naming tuỳ tiện

GET /getUserData
GET /fetchUserInfo
GET /queryUserById
GET /users/query

4 API cùng chức năng, naming khác hết. Newbie onboard confused.

Scene 2: Error handling lung tung

json
// Có cái return HTTP status
HTTP/1.1 404 Not Found

// Có cái return 200 + code
HTTP/1.1 200 OK
{ "code": 404, "message": "User không tồn tại" }

// Có cái throw exception
HTTP/1.1 200 OK
{ "error": "Có lỗi" }

FE không biết judge request success thế nào.

Scene 3: Response structure khác nhau

json
{ "data": { ... } }
{ "result": { ... } }
{ "content": { ... } }

Mỗi API format khác, FE phải handle riêng từng cái.

API design tốt = menu nhà hàng: rõ, quy trình chuẩn, error có hint.


1. API là gì?

API = "thoả thuận đối thoại giữa program".

Ẩn dụ nhà hàng

RoleAPINote
MenuAPI docCho biết "món" nào order
Phục vụHTTP protocol"Đối thoại" chuẩn
BếpServerTheo "order" xử
Mang mónResponseTrả kết quả
API 请求演示
// 点击下方按钮,模拟不同的 API 请求
>
💻客户端发起请求
等待请求...
HTTP Request
🖥️服务器处理请求
等待中...
HTTP Response
📦响应返回结果
等待响应...
💡 点击命令按钮,观察一次完整的 API 请求-响应流程。

2. API design philosophy

4 mainstream style:

🎨四种 API 风格对比

REST

最常用

Representational State Transfer,表述性状态转移。由 Roy Fielding 于 2000 年在其博士论文中提出。面向资源,用 URL 标识资源,用 HTTP 方法操作资源。

示例:获取用户信息
GET    /users           # 获取用户列表
GET    /users/123       # 获取单个用户
POST   /users           # 创建用户
PUT    /users/123       # 全量更新
PATCH  /users/123       # 部分更新
DELETE /users/123       # 删除用户
核心特点
URL 是名词,不是动词
使用 HTTP 方法表达操作
无状态,请求包含所有信息
可缓存,支持分层系统
适用场景公开 API、CRUD 操作、资源边界清晰的业务
📊 风格速览对比
特性
RPC
REST
GraphQL
gRPC
核心理念
面向过程
面向资源
面向数据
面向方法
URL 风格
动词为主
名词为主
单一端点
不依赖URL
学习曲线
性能
一般
一般
较好
优秀
使用占比
~30%
~50%
~15%
~5%

2.1 REST vs RESTful

ConceptNghĩa
RESTArchitecture style, set of constraints (Roy Fielding)
RESTfulTính từ, mô tả API tuân theo REST

REST 6 constraints

  1. Client-server separation: FE-BE độc lập
  2. Stateless: mỗi request chứa đủ info, server không lưu session
  3. Cacheable: response mark cacheable không, tăng perf
  4. Uniform interface: dùng HTTP method + status code chuẩn
  5. Layered system: client không cần biết connect layer nào
  6. Code on demand (optional): server extend client function

Sao REST phổ biến nhất?

  1. Learning cost thấp (HTTP sẵn embody REST)
  2. Ecosystem chín muồi
  3. Universal (mọi ngôn ngữ, platform)
  4. Cacheable (GET cacheable native, CDN-friendly)

3. RESTful: URL "biết nói"

REST core:

  • Abstract things → Resource
  • URL identify resource
  • HTTP method operate resource

3.1 Ẩn dụ kho

Concept khoRESTVd
Shelf addressURL/users, /orders
Op cáchHTTP methodGET (xem), POST (nhập)
HàngResourceUser data, order data

Key: URL là noun, không phải verb.

3.2 URL design rules

Rule Sai ĐúngNote
Dùng noun không verb/getUsers/usersURL = resource, HTTP method = action
Plural/user/usersUnified
Lowercase + hyphen/UserProfiles/user-profilesURL case-sensitive
Avoid deep hierarchy/a/b/c/d/e/a/b/cMax 3 levels
Filter qua query param/products/phone/5000/products?cat=phoneFilter qua ?

3.3 HTTP method

MethodUseIdempotentSafe
GETLấy
POSTTạoKhôngKhông
PUTUpdate fullKhông
PATCHUpdate partialKhôngKhông
DELETEXoáKhông

4. Status code

ClassNghĩaCodes
2xxSuccess200, 201, 204
3xxRedirect301, 304
4xxClient error400, 401, 404
5xxServer error500, 503
HTTP 状态码演示
// 点击按钮查看不同状态码的含义
>
2xx 成功
200OK请求成功
201Created创建成功
204No Content成功但无返回内容
⚠️4xx 客户端错误
400Bad Request请求格式错误
401Unauthorized未认证
403Forbidden无权限
404Not Found资源不存在
422Unprocessable语义错误
429Too Many请求过多
🔴5xx 服务端错误
500Server Error服务器内部错误
502Bad Gateway网关错误
503Unavailable服务不可用
💡 点击命令按钮,了解常见的 HTTP 状态码。

5. Error handling: "reject" elegant

Pits

Pit 1: mọi error return 200

json
// ❌
HTTP/1.1 200 OK
{ "error": "Có lỗi" }

Cache layer cache "success" response, monitor không phát hiện.

Pit 2: error message quá chung chung

json
// ❌
HTTP/1.1 400 Bad Request
{ "message": "Param sai" }

Client không biết param nào sai, sao sai.

Pit 3: Expose sensitive

json
// ❌ Dangerous
HTTP/1.1 500 Internal Server Error
{ "stack": "at UserService.login...", "sql": "SELECT * FROM..." }

Lộ code structure + SQL → attacker exploit.

错误处理演示
// 对比好的和差的错误处理方式
>
响应结构
点击上方按钮查看错误响应示例
💡 点击按钮,对比"好的"和"差的"错误响应设计。

6. Version control: "backward compatibility" API

Sao cần?

App có 1 triệu user, cần sửa order API.

  • Không version: New app call new API → OK. Old app call new API → field missing, crash!
  • Đúng: /v1/orders (cũ), /v2/orders (mới + feature mới)

Strategy

StrategyVdƯuNhược
URL path/v1/usersTrực quan, cacheableURL dài
Request headerAccept: vnd.api.v2+jsonURL sạchKhó debug
Query param/users?version=2Đơn giảnKhông chuẩn

Best practice

  • Backward compatible: v1 maintain 6-12 tháng, cho client upgrade
  • Doc sync: mỗi version doc riêng
  • Deprecation notice: thông báo trước v1 down
  • Monitor: stats call v1, confirm an toàn mới stop

7. Response structure design

📋API 响应结构设计

为什么要统一响应格式?

❌ 问题:不同接口返回格式不一致
// 接口 A
{ "data": { "user": {...} } }

// 接口 B
{ "result": { "user": {...} } }

// 接口 C
{ "user": {...} }
前端需要针对每个接口单独处理,代码冗余,容易出错
✅ 解决:统一响应格式
{
  "code": 0,
  "message": "success",
  "data": { ... },
  "request_id": "req-xxx"
}
💡request_id 用于问题追踪,建议使用 UUID v4 或雪花算法生成

7.1 Big company practice

Google API Design Guide
json
{
  "error": {
    "code": 429,
    "message": "Resource exhausted",
    "status": "RESOURCE_EXHAUSTED",
    "details": [
      {
        "@type": "type.googleapis.com/google.rpc.ErrorInfo",
        "reason": "RESOURCE_AVAILABILITY",
        "domain": "compute.googleapis.com"
      }
    ]
  }
}

Core: ErrorInfo machine-readable, message cho dev rõ, detailsLocalizedMessage, Help.

Microsoft REST API Guidelines
  • Error (4xx): client gửi data invalid
  • Fault (5xx): server không respond được valid request
  • Response header: Date (RFC 5322), Content-Type, ETag cho optimistic concurrency
Stripe API
json
{
  "error": {
    "type": "card_error",
    "code": "card_declined",
    "message": "Your card was declined.",
    "param": "number",
    "decline_code": "insufficient_funds",
    "doc_url": "https://stripe.com/docs/error-codes/card-declined"
  }
}

Đỉnh: type (api_error, card_error, invalid_request_error), param chỉ chính xác field sai, doc_url link doc.

JSON:API Specification
json
{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": { "title": "..." },
    "relationships": {
      "author": { "data": { "type": "users", "id": "9" } }
    }
  },
  "included": [
    { "type": "users", "id": "9", "attributes": { "name": "Hoàng" } }
  ]
}

data main, included tránh duplicate request.

GitHub REST API

Success:

json
{
  "id": 1296269,
  "name": "Hello-World",
  "owner": { "login": "octocat", "avatar_url": "..." },
  "html_url": "https://github.com/octocat/Hello-World"
}

Error:

json
{ "message": "Bad credentials", "documentation_url": "https://docs.github.com/rest" }

Đỉnh: multiple URL format, Link header cho pagination.

7.2 Best practice tổng kết

  1. Consistency: mọi API cùng response structure, FE wrap request layer thống nhất
  2. Machine-readable: error code + reason để code auto-handle
  3. Human-friendly: message rõ, kèm suggestion
  4. Traceable: request_id xuyên full chain, debug dễ
  5. i18n: details extend localized message

7.3 data field design

📦data 字段设计规范

单对象 vs 列表

单对象
{
  "code": 0,
  "data": {
    "id": 123,
    "name": "张三"
  }
}
列表
{
  "code": 0,
  "data": {
    "items": [...],
    "pagination": {
      "page": 1,
      "total": 100
    }
  }
}
列表数据包裹在 items 数组中,分页信息放在 pagination 对象
💡参考 ISO 8601 时间标准,字段命名保持 snake_case 风格

7.4 Error response advanced

⚠️错误响应设计进阶

参数校验错误

{
  "code": 10001,
  "message": "参数校验失败",
  "data": {
    "errors": [
      {
        "field": "email",
        "message": "邮箱格式不正确",
        "value": "invalid-email"
      },
      {
        "field": "password",
        "message": "密码长度至少 8 位",
        "value": "123"
      }
    ]
  }
}
field出错字段名,前端可定位表单
message用户友好的错误描述
value客户端提交的值(可选)
💡错误信息要"机器可读 + 人类友好",便于前端统一处理

8. Thực chiến: e-commerce API

# User module
GET    /v1/users                    # List
POST   /v1/users                    # Create
GET    /v1/users/{id}               # Detail
PUT    /v1/users/{id}               # Update full
PATCH  /v1/users/{id}               # Update partial
DELETE /v1/users/{id}               # Delete

# Order module
GET    /v1/users/{id}/orders        # User's orders
POST   /v1/orders                   # Create order
GET    /v1/orders/{id}              # Order detail
PATCH  /v1/orders/{id}/status       # Update status

# Product (complex filter qua query)
GET    /v1/products?category=phone&price_max=5000&sort=price_desc&page=1

9. AI hỗ trợ design API

Prompt template

Bạn là senior backend architect, giỏi RESTful API design.

## Business
[Mô tả scenario]

## Functional requirements
[List modules]

## Design requirements
1. RESTful compliant
2. URL: noun plural, lowercase + hyphen
3. HTTP method đúng (GET/POST/PUT/PATCH/DELETE)
4. Response format thống nhất: { code, message, data, request_id }
5. Status code hợp lý
6. Versioning: URL path (/v1/)

## Output
- Table API list (method, URL, desc, body, response)
- Key API examples
- Status code list

AI assist notes

NoteNote
Provide full contextBusiness, role, data relationship
Explicit constraintNaming, version, format
IterateFirst output không hoàn hảo, follow-up
Human reviewCheck vs business requirement
Edge casesError handling, permission, pagination

Follow-up technique

  • "Add error response example cho mỗi API"
  • "Cân nhắc pagination, sort, filter param"
  • "Add permission control cho API"
  • "Check vs RESTful best practice"

Glossary

TermFullNote
APIApplication Programming Interface-
RESTRepresentational State TransferArchitecture style
Resource-Core concept REST, URL unique
Idempotency-Multi exec same result
Status Code-HTTP response status
Versioning-New + old API coexist
Request Body-POST/PUT/PATCH data
Response Body-Server return
Authentication-"Bạn là ai" (login, token)
Authorization-"Bạn làm được gì" (permission)

2026 cho VN dev

  • OpenAPI 3.1: spec chuẩn, dùng để gen SDK + doc
  • tRPC: end-to-end type safety cho TypeScript stack
  • Hono RPC: lightweight, edge-friendly
  • GraphQL: cho complex relation query (Facebook, Shopify)
  • gRPC: cho microservice internal (high perf)
  • VN context: public API → REST + OpenAPI; internal microservice → gRPC; mobile/web → REST hoặc tRPC
  • AI API: theo OpenAI standard (chat completions, function calling)