干后端这么多年,见过的接口比见过的产品经理还多。今天不整那些"RESTful最佳实践"的废话,咱们来聊聊我踩过的坑、流过的泪、以及那些让我半夜惊醒的代码设计。
1. 错误处理:别让你的用户猜谜
想象一下这个场景:用户调用你的API,返回了个500,然后?然后用户就懵了。
我见过最离谱的错误响应是这样的:
{
"error": true,
"message": "Something went wrong"
}
Something went wrong???你是要我猜谜吗?是我传参错了?还是你服务器着火了?
一个合格的错误响应应该长这样:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "用户名不能为空或包含特殊字符",
"field": "username",
"request_id": "req_abc123"
}
}
看到没?用户一看就知道自己错哪儿了,开发者一看request_id就能去日志里捞详细信息。这才叫有用的错误信息,不是"出错了"三个字打发人。
2. 状态码:别为了省事全返回200
我知道你懒,我也懒。但把业务错误全塞进200里返回的写法,真的会让你未来的自己和同事想穿越回来揍现在的你。
来看看HTTP状态码的正确打开方式:
- 200 - 成功,且只有真正成功才用
- 201 - 资源创建成功(POST/PUT成功)
- 400 - 客户端参数有问题
- 401 - 没登录/认证失败
- 403 - 登录了但没权限
- 404 - 资源不存在
- 429 - 请求太频繁了
- 500 - 服务器爆炸了(很少见,真的)
最骚的操作是返回一个200但body里写着"status": "failed",然后让前端去解析这个字段判断成功还是失败。这种设计,代码review的时候我真的会骂人。
3. 分页:别一次性返回全表数据
有一天DBA给我发消息:"你们接口把3千万用户数据一次性全查出来了,服务器差点原地升天。"
我一看代码,果然,select * from users,没有limit,没有分页。生产事故+1。
分页的正确姿势:
GET /api/users?page=2&per_page=20
{
"data": [...],
"pagination": {
"current_page": 2,
"per_page": 20,
"total": 3000,
"total_pages": 150,
"has_next": true,
"has_prev": true
}
}
_cursor pagination_也是个好东西,特别适合实时数据流场景,但实现起来稍微复杂点,看业务需求选择。
4. 版本控制:你的API需要退休计划
当年我接手过一个项目,API v1到v5共存,每个版本的逻辑还略有不同。最离谱的是一个支付接口,v1、v2、v3的差异在于字段名的命名风格——下划线、驼峰、全大写各来一套。
API版本管理的几个原则:
- URL版本化最直观:
/api/v1/usersvs/api/v2/users - 主版本升级要有充分deprecation周期,提前通知调用方
- 小改动不升版本,加字段不升版本,改字段搞清如何兼容
- 老版本要有明确的下线时间表,别无限制维护下去
有个血泪教训:当初有个接口文档写的是"3个月后下线v1",结果三年过去了还在跑。原因是调用方太多又联系不上。所以,设计API第一天就要想好它的退休计划。
5. 幂等性:让你的接口可以安全重试
网络是不可靠的,用户会手抖点两下,CDN可能偶尔发两次请求。这时候如果你的接口不支持幂等,就会出现重复数据、重复扣款之类的灾难。
几个常见场景的幂等实现:
- POST创建:用幂等key(idempotency-key),相同key的请求返回相同结果
- POST支付:服务端存储支付流水号,重复请求直接返回已支付
- DELETE删除:本身是幂等的,但最好改成软删除并返回一致的结果
POST /api/orders
Headers: {
"Idempotency-Key": "order_unique_123"
}
这个header的价值在于:就算网络超时前端重试了,服务端也不会创建两条订单。
6. 文档:代码写完文档就没用了?不存在的
我一直坚信一句话:没有文档的API等于没有API。
好的API文档应该包括:
- 每个endpoint的功能说明
- 请求参数的类型、必填/可选、取值范围
- 响应结构和各字段含义
- 错误码说明
- 调用示例(最好能直接跑)
- 认证方式和请求频率限制
推荐工具:OpenAPI/Swagger规范,写一次文档能同时生成客户端SDK和测试界面,真香。
写到最后
API设计这事儿,说难听点就是"坑都在那里,你踩不踩而已"。但凡我早年能有人跟我讲讲这些,不至于在生产环境留下那么多历史遗产。
记住一个核心原则:你的API是给别人用的,要站在调用方的角度想问题。你觉得简洁的写法,不一定是对方容易理解的写法。
少一点套路,多一点真诚。让天下没有难用的API,从你我做起。
下期见,peace。