老板:"这接口返回的字段又不对了!" 我:"文档上写了的..." 老板:"那你把文档给我看看。" 我(打开Swagger UI):"喏,这儿都有。"
老板看完,沉默了。
一个好的接口文档,能让前后端的沟通成本直线下降。今天聊聊,怎么设计接口文档,让团队协作更顺畅。
原文地址
问题是:接口为什么总在改?
三个常见的乱象
乱象一:接口命名全看心情
yaml
GET /api/getUserInfo?id=123
GET /api/query_user_data
GET /api/userInfoGet
这三个接口,你能一眼看出它们是干啥的?反正我不能。
乱象二:返回字段看后端心情
json
GET /api/user/123
{
"name": "张三",
"avatar": "http://...",
"phone": "138xxxx",
"orders": [...],
"lastLoginIp": "..."
}
这次返了 phone,下次可能没了。这个字段谁要的?不知道。反正后端开心就好。
乱象三:文档靠嘴说
"那个接口你调用一下,参数我微信发你..." "这个字段应该可选的..." "接口改了,你那边同步一下..."
结果:谁也说不清接口长什么样。前端凭感觉猜,后端凭记忆改。
乱象的根源
没有统一的"契约"。
前端不知道后端返什么,后端不知道前端要什么。大家靠口头沟通,靠微信同步。改一次,扯皮一次。
解决方案一:RESTful 设计规范
什么是 RESTful?
REST = Representational State Transfer,说人话就是:
用 URL 表示"东西",用 HTTP 方法表示"动作"。
就像去餐厅点餐:你说"来一份宫保鸡丁",服务员知道你要吃的,不需要多解释。
核心原则一:名词,而不是动词
yaml
# ❌ 错误示范:动词在 URL 里
GET /api/getUser
POST /api/createOrder
DELETE /api/deleteUserById
# ✅ 正确姿势:名词表示资源,HTTP方法表示动作
GET /api/users # 获取用户列表
GET /api/users/123 # 获取单个用户
POST /api/users # 创建用户
PUT /api/users/123 # 更新用户
DELETE /api/users/123 # 删除用户
核心原则二:资源要分层级
yaml
# 用户123的订单列表
GET /users/123/orders
# 订单456的物流信息
GET /orders/456/delivery
# 物流公司是谁
GET /delivery/789/carrier
核心原则三:状态码要对
| 状态码 | 含义 | 什么情况用 |
|---|---|---|
| 200 | OK | 成功返回数据 |
| 201 | Created | 创建成功 |
| 400 | Bad Request | 参数有问题 |
| 401 | Unauthorized | 没登录 |
| 403 | Forbidden | 没权限 |
| 404 | Not Found | 资源不存在 |
| 500 | Server Error | 服务器挂了 |
核心原则四:版本要管理
yaml
# 接口升级,不影响老客户端
GET /api/v1/users
GET /api/v2/users
解决方案二:GraphQL 按需取用
RESTful 的局限
假设有三个页面:
yaml
# 列表页只需要:用户名、头像
GET /api/users
# 详情页需要:用户名、头像、手机号、地址
GET /api/users/123
# 但 REST 做不到的事:
# "列表页我只想要 name 和 avatar,别的别给我!"
REST 一次请求只能拿"一份资源"。不管你需要几个字段,后端把整个对象都返给你。列表页拿了一堆用不上的数据,移动端流量白白浪费。
GraphQL:我要什么,你给什么
GraphQL = 我来指定要哪些字段,你只返这些。
yaml
REST(套餐制):
GET /api/user/123
不管你要不要,都返给你所有字段 → 浪费
GraphQL(自助餐):
POST /graphql
我只想要 name 和 avatar,你只返这两个 → 省流量
GraphQL 三板斧
Query --- 查数据
graphql
query {
user(id: "123") {
name
avatar
email
}
}
Mutation --- 改数据
graphql
mutation {
updateUser(id: "123", input: { name: "张三新" }) {
id
name
}
}
Subscription --- 实时推送
graphql
subscription {
onNewMessage(roomId: "456") {
id
content
}
}
光有规范不够:还需要文档
为什么文档比代码重要?
text
代码是给机器看的
文档是给人看的
前端调用接口,看的是文档,不是代码。一份好的文档让前端可以独立开发,不用每次都问后端。
Swagger:文档自动生成
很多人觉得写文档麻烦,其实是因为没选对工具。
yaml
后端写代码 + 注解
↓
Swagger 自动扫描
↓
生成 JSON Schema
↓
打开 /swagger-ui.html
↓
人人可看、人人可调!
java
# Java + SpringBoot 示例
@RestController
@RequestMapping("/api/users")
public class UserController {
@ApiOperation("获取用户列表")
@GetMapping
public Result<Page<User>> listUsers(
@ApiParam("页码") @RequestParam(defaultValue = "1") int page,
@ApiParam("每页数量") @RequestParam(defaultValue = "10") int size
) {
return Result.success(userService.list(page, size));
}
}
写好注解,文档就自动生成了。前端打开页面就能看到所有接口,参数说明一目了然。
文档 checklist
一份合格的 API 文档,应该包含这些:
| 必须包含 | 说明 |
|---|---|
接口地址 |
URL + HTTP 方法 |
请求参数 |
参数名、类型、是否必填、示例值 |
返回数据 |
字段名、类型、含义、示例 |
错误码 |
每种错误代表什么 |
版本信息 |
当前版本、更新时间 |
一张图:怎么选?
yaml
接口复杂度低?
↓
RESTful + Swagger 够了
多端需要不同字段?
↓
GraphQL 或 BFF
共同要求:规范 + 文档,缺一不可!
实战:新项目怎么做?
yaml
1. 定义资源
- 有哪些"东西"要管理?用户、商品、订单...
2. 设计 URL 规范
- /api/v1/users
- /api/v1/products
3. 选择方案
- 小项目 → RESTful + Swagger
- 多端适配 → GraphQL
4. 生成文档
- 后端写注解 → Swagger 自动生成
- 前端自己看文档开发
5. 开会确认
- 文档即契约,双方签字
写在最后
那天老板看完 Swagger 文档后说的第一句话是:
"以后新接口,都按这个标准来。"
然后转头对前端说:
"有问题先看文档,别动不动就问后端。"
一份好的接口文档,胜过大段代码注释。它是团队的"契约",减少沟通成本,让前后端可以独立工作。
下次老板问你接口怎么设计,你就把 Swagger 甩给他看。