API 设计的一些想法
做了几年前后端对接,见过好的 API,也见过让人抓狂的。这里记录一些经验。
RESTful 是好,但别教条
有些团队非要严格执行 RESTful,结果:
GET /users # 获取列表
POST /users # 创建
GET /users/:id # 获取详情
PUT /users/:id # 更新
DELETE /users/:id # 删除
看起来很标准对吧?但遇到复杂场景就尴尬了:
- 批量删除怎么办?
- 搜索算 GET 还是 POST?
- 登录算哪个资源?
我的建议:RESTful 作为基础风格,特殊情况该破就破。
// 批量操作
POST /users/batch-delete
// 复杂查询
POST /users/search
// 登录
POST /auth/login
统一响应格式
interface ApiResponse<T> {
code: number;
message: string;
data: T;
}
不管成功失败,格式一致。前端处理起来方便很多。
错误响应也要有结构:
{
"code": 40001,
"message": "参数错误",
"errors": [
{ "field": "email", "message": "邮箱格式不正确" }
]
}
分页的坑
最头疼的是分页参数不统一。有的用 page/size,有的用 offset/limit,还有的自己发明格式。
建议:
interface PaginationParams {
page: number; // 从 1 开始
pageSize: number;
}
interface PaginatedResponse<T> {
list: T[];
total: number;
page: number;
pageSize: number;
totalPages: number;
}
版本控制
API 一定会变,提前规划好版本策略。
两种常见方式:
# URL 版本
/api/v1/users
/api/v2/users
# Header 版本
GET /api/users
Accept: application/vnd.myapi.v2+json
URL 版本更直观,Header 更灵活。我们用的 URL 版本,简单粗暴。
文档
没有文档的 API 等于不存在。
我们用 Swagger/OpenAPI,自动生成文档:
openapi: 3.0.0
paths:
/users:
get:
summary: 获取用户列表
parameters:
- name: page
in: query
schema:
type: integer
responses:
'200':
description: 成功
前端可以直接看文档,不用再去问后端了。
最后
好的 API 设计是双向的。前端要多提需求,后端要多考虑使用场景。别搞成后端写完前端骂娘的循环。