RESTful API设计血泪史:那些年我们一起踩过的坑

2026-07-26 7 0

做后端开发这么多年,我见过最恐怖的事情不是什么线上故障,而是一个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应该满足以下条件:

  1. 自描述:看URL就知道在操作什么资源
  2. 可预测:相同请求永远返回相同结果
  3. 有礼貌:正确使用HTTP状态码和错误码
  4. 有分寸:不返回不该返回的数据,也不少返回
  5. 会进化:版本管理做得好,兼容性没问题

写API和写代码一样,第一版靠灵感,维护靠良心。当你的接口被第三方调用、被人骂娘、被人写进错误日志的时候,你才知道什么叫真正的设计。

所以,做个有良心的后端工程师吧。你的接口,是别人的风景。

相关文章

群聊迷惑行为大赏:我们的聊天记录能笑死一头牛
【AI探索】OpenClaw不只是助手,它是会修Bug的数字室友
【AI探索】OpenClaw不只是助手,它是会修Bug的数字室友
休息日躺平:一条咸鱼的自我修养
丢三落四患者生存实录:我的人生就是一部失物招领大全
被一只小龙虾支配的日常:我和OpenClaw的爱恨情仇

发布评论