做后端开发这么多年,我见过最恐怖的事情不是什么线上故障,而是一个POST /addUser这种接口名。有人管这叫"RESTful",我管这叫"让人想离职"。
RESTful不是填空题,是设计哲学
很多人对RESTful的理解就是:把动作换成HTTP方法,把资源名改成复数形式。于是:
- GET /getUsers → GET /users ✓
- POST /createUser → POST /users ✓
- DELETE /deleteUser/123 → DELETE /users/123 ✓
恭喜你,你刚及格了。但及格距离优秀还有十万八千里。
URL设计:少即是多
见过最离谱的接口长这样:
GET /api/v1/user/123/orders/456/items?status=pending&page=1&size=20&sort=created_at&order=desc
这是URL还是函数签名?我数了一下,5层嵌套,还有一个query string比某些朋友圈还长。
好的URL应该像这样:
GET /users/123/orders?status=pending&page=1
层级控制在2-3层以内。orders已经是users的子资源了,不需要再套items。用filter参数处理查询,而不是无限嵌套。
HTTP状态码:别只会200和500
某接口返回:
{ "code": 200, "message": "success", "data": null }
我问开发为什么data是null,他说"因为查不到数据"。我说那你HTTP状态码呢?他说"200啊,成功嘛"。
我的血压瞬间也200了。
正确做法:
- 资源不存在 → 404
- 参数校验失败 → 400
- 未授权 → 401
- 权限不足 → 403
- 服务器炸了 → 500(这个一般不是你的锅,是运维的)
错误响应:给开发者一条活路
最烂的错误响应:
{ "error": "操作失败" }
操作失败是什么鬼?是我网络断了?还是数据库挂了?还是我传错参数了?开发者看这种错误,日志都懒得查了,直接重试三次再骂产品经理。
正确的错误响应应该长这样:
{ "error": { "code": "VALIDATION_FAILED", "message": "参数校验失败", "details": [ { "field": "email", "reason": "邮箱格式不正确" }, { "field": "password", "reason": "密码长度不能少于8位" } ] }}
有错误码、有人类可读的消息、有具体哪个字段出了问题。这才叫"为开发者着想"。
版本管理:不要让旧代码突然暴毙
有一种灾难叫"没打招呼就改了接口"。比如原来返回:
{ "id": 123, "name": "张三", "email": "zhangsan@example.com" }
某天产品说"加个手机号",开发直接在原结构上加了个phone字段。某前端的name取值逻辑是response.name,结果新版本直接崩了。
正确做法:
GET /api/v1/users/123 // 旧版本,保留
GET /api/v2/users/123 // 新版本,加了phone字段
加版本号不是矫情,是给别人留条活路。你改你的,我用我的,互不影响。
分页:无限滚动是美丽的谎言
很多APP说"无限滚动,不限页码"。听起来很美好,实际上是性能地狱。
当你用OFFSET 100000的时候,数据库已经在翻白眼了。用户其实很少会翻到第100页,他们只是想找特定的东西。
正确做法:
GET /articles?cursor=eyJpZCI6MTIzfQ&limit=20
Cursor-based pagination(游标分页)的好处:性能稳定,不随页码增加而变慢。你在第100页的性能和在第1页一样好。
幂等性:重复请求不是bug,是feature
用户下单时网络抖了一下,于是连点两次。系统:"订单创建成功!" "订单创建成功!" 用户:"我X,两笔订单?"
所有写操作都要考虑幂等性:
- POST /orders → 创建订单(不幂等,每次创建新订单)
- POST /orders/generate-id → 生成订单号(幂等,返回同一订单号)
- PUT /orders/123/pay → 支付订单(幂等,重复支付返回同样结果)
用幂等令牌(Idempotency Key)是标准做法。客户端生成一个UUID,服务端存储处理结果,重复请求直接返回缓存结果。
总结:好API的标准
一个好的API应该满足以下条件:
- 自描述:看URL就知道在操作什么资源
- 可预测:相同请求永远返回相同结果
- 有礼貌:正确使用HTTP状态码和错误码
- 有分寸:不返回不该返回的数据,也不少返回
- 会进化:版本管理做得好,兼容性没问题
写API和写代码一样,第一版靠灵感,维护靠良心。当你的接口被第三方调用、被人骂娘、被人写进错误日志的时候,你才知道什么叫真正的设计。
所以,做个有良心的后端工程师吧。你的接口,是别人的风景。