为什么你的API总是被吐槽?我总结了7个血泪教训

2026-03-31 10 0

做后端开发这些年,我见过太多API设计得让人想骂娘的代码。有些接口返回的数据结构跟盲盒一样,你永远不知道下一个字段是什么;有些接口文档写得跟小说似的,实际调用起来发现全是坑。今天我就把这些年踩过的坑整理出来,保证每一条都是真实案例,看完保证让你有种「这不就是我写的吗」的共鸣。

教训一:返回结构混乱,同一个接口两种脸

先说个我亲眼见过的骚操作。有个兄弟写的用户查询接口,成功返回用户信息,失败返回 {"error": "用户不存在"}。好家伙,成功是对象,失败是字符串,你要我在前端做类型判断吗?

正确的做法是统一返回结构:

{
  "code": 200,
  "message": "success",
  "data": {
    "id": 123,
    "name": "张三"
  }
}

// 错误时也返回同样的结构
{
  "code": 404,
  "message": "用户不存在",
  "data": null
}

记住:一个接口,永远只有一种返回结构。不管是200还是500,返回的JSON顶层key必须一致。前端处理起来爽,大家都是打工的,何必互相为难。

教训二:分页参数随心所欲,页码从0还是1开始全凭心情

这个问题简直是后端界的月经题。offset=0 还是 offset=1?page=1 还是 page=0?limit 默认多少?

我建议你用这套方案:

  • 使用 offsetlimit,而不是 pagepage_size
  • offset 从 0 开始(程序员都懂)
  • limit 默认值 20,上限 100(防手滑)
  • 返回时带上总数和总页数

完整分页返回应该是这样:

{
  "code": 200,
  "data": {
    "list": [...],
    "pagination": {
      "total": 1000,
      "page": 1,
      "page_size": 20,
      "total_pages": 50
    }
  }
}

最最重要的是,文档里要写清楚!不要让调用方猜。

教训三:HTTP状态码乱用,200表示失败400表示成功

这个我真的遇到过。有一个接口,逻辑是「创建订单成功返回200,库存不足返回400」。我看到400状态码时第一反应是「我参数写错了?」,结果看了半天文档才发现,400在这里的意思是「业务逻辑上的失败」。

HTTP状态码是有规范的,不是你想怎么用就怎么用:

  • 200:请求成功,服务端处理正常
  • 400:客户端参数错误,请求格式不对
  • 401:未认证,请先登录
  • 403:已认证但没权限
  • 404:资源不存在
  • 500:服务端内部错误

如果你的「库存不足」是一种业务层面的失败,而不是用户输入的问题,请用200+业务错误码来处理。

教训四:接口版本管理?不存在的

很多小团队觉得「我们用户少,不需要做版本管理」。然后某天你改了一个字段,发现线上十几家客户全部炸了。

API版本管理是必须要做的,推荐的做法:

https://api.example.com/v1/users
https://api.example.com/v2/users

每个版本至少维护一年,老版本给足够的迁移时间。如果不想在URL里放版本号,至少在Header里处理:

Accept: application/vnd.example.v2+json

教训五:字段命名随心所欲,user_name 和 userName 和 userNameCN 同时存在

这个问题在团队协作时特别明显。有人说用下划线(user_name),有人觉得驼峰更优雅(userName),最后出来的接口四不像。

选一种规范,全团队统一。我的建议:

  • 对外API用驼峰(JSON标准)
  • 数据库字段用下划线(数据库惯例)
  • 文档里明确说明

最怕的是同一个项目里混用,调用方要看两遍文档才能确定字段名,效率低下还容易出错。

教训六:接口文档过时了,以为在维护其实早已放弃

我见过最离谱的是一个团队的API文档,上面的「获取用户信息」接口返回字段有20多个,实际接口只返回8个。我问他们为什么,他们说「那个文档是两年前写的,后来删了一些字段但文档没更新」。

解决方案:

  1. 使用 Swagger/OpenAPI 规范编写文档,代码即文档
  2. 文档和代码必须同版本管理,改代码必须改文档
  3. 考虑用 API Mock 工具,让调用方能直接测试

一个好的文档应该包含:请求参数、返回字段、错误码示例、调用频率限制。如果你的文档三行字就结束了,那不叫文档,叫简历。

教训七:没有考虑向后兼容,删字段跟删好友一样随意

你永远不知道调用方在用你哪个字段。有个真实的教训:某产品觉得 nickname 字段没人用就删了,结果有客户的App直接读取这个字段展示用户名,删完之后那家客户的用户全部显示「匿名用户」。

删字段的正确姿势

  1. 先标记为 deprecated,保留返回但提示「即将废弃」
  2. 等至少一个版本周期后再删除
  3. 删除前发邮件/公告通知所有集成方
  4. 宁可返回null也不能直接删字段

记住:你对API的任何改动都是重大决定,不是你一个人的事,是所有集成方的事。


写在最后

API设计这件事,说难听点就是「细节决定成败,习惯决定细节」。很多人觉得接口能跑就行,但真正考验功力的恰恰是这些看似无关紧要的设计选择。

好的API设计有三个标准:

  1. 一致性:所有接口遵循同一套规范
  2. 可预测性:调用方能猜到你的返回
  3. 文档完整性:文档和代码一样重要

下次写接口之前,先问自己三个问题:这个接口给谁用?对方看到返回会骂我吗?这个接口三个月后我还能看懂吗?

如果三个问题都能回答好,那你的接口至少不会被人追着骂了。至于能不能被人夸,那就需要更多的实战经验了——比如今天这篇文章没讲到的「RESTful到底怎么用」「GraphQL值不值得上」这些话题,留着下次再聊。

祝大家的API都被夸,不被骂。

相关文章

不想折腾了?让小龙虾帮你一键部署 AI 工具!🦞
不想折腾了?让小龙虾帮你一键部署 AI 工具!🦞
你的HTTP重试,是一颗随时会炸的定时炸弹
你的API正在悄悄谋杀你的数据库——而你可能毫不知情
还在为部署AI工具熬夜?小龙虾帮你躺平!🦞
还在为部署AI工具熬夜?小龙虾帮你躺平!🦞

发布评论