为什么你的API设计是垃圾——以及如何抢救一下

2026-05-13 11 0

为什么你的API设计是垃圾——以及如何抢救一下

昨晚又看到一份API文档,状态码返回200但body里写着{"code": 500, "message": "服务器爆炸"}。我沉默了三秒,然后关掉了浏览器。

这大概是很多程序员的日常:后端写接口,前端猜接口,全靠玄学通信。本文不教你背REST规范,只聊几个实际点的东西。

1. 状态码是用来用的,不是用来装饰的

有些人把HTTP状态码当成装饰品,200是绿色的所以什么都返回200。这不叫REST,这叫"我觉得200比较好看"。

实际场景:

// 你的接口
GET /api/users/123

// 返回
{
  "code": 404,
  "message": "用户不存在",
  "data": null
}

// 状态码:200 ✓ (设计师看了想打人)

正确做法:找不到就404,东西删了就204,服务器炸了就500。别在body里写剧本,状态码就是你的台词。

// 正确姿势
GET /api/users/123

// 找不到?404
// 找到了?200 + 数据
// 服务器炸了?500 + error对象

记住:状态码是给机器看的,body是给人看的。别让机器读你的剧本。

2. 命名:少一点套路,多一点真诚

见过最离谱的接口命名:

/api/v1/user/getInfoById
/api/v1/user/queryUserList
/api/v1/user/modifyUser
/api/v1/user/deleteUser

这是把接口当方法名在写。REST不是这样的。

资源思维 vs 操作思维:

// 操作思维(烂)
POST /api/createUser
POST /api/deleteUser
POST /api/updateUser

// 资源思维(好)
POST   /api/users      // 创建
GET    /api/users      // 列表
GET    /api/users/123  // 单个
PUT    /api/users/123  // 更新
DELETE /api/users/123  // 删除

名词复数,动词用HTTP方法。这不是我发明的,这是1994年就存在的共识。你不需要发明轮子,你需要的是停止发明奇怪的轮子。

3. 分页:别让前端来"猜"还有多少数据

// 某些人的分页(灵魂拷问版)
{
  "data": [...],
  "page": 1
}

前端:你倒是告诉我有没有下一页啊??

标准分页响应应该长这样:

{
  "data": [...],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "total": 1000,
    "totalPages": 50,
    "hasMore": true
  }
}

或者用游标分页:

{
  "data": [...],
  "nextCursor": "eyJpZCI6MTI1fQ==",
  "hasMore": true
}

给前端留条活路。你写的接口是给人调用的,不是拿来考前端读心术的。

4. 错误信息:请写人话

// 错误示例
{
  "code": -1,
  "message": "操作失败",
  "error": "UNKNOWN_ERROR"
}

前端:好的,那我展示"操作失败"。用户:???

好的错误响应应该包含:

{
  "error": {
    "code": "USER_NOT_FOUND",
    "message": "用户不存在,请检查输入的手机号",
    "field": "userId",
    "documentation": "https://api.example.com/errors/USER_NOT_FOUND"
  }
}

告诉用户:发生了什么、哪里出了问题、怎么解决。如果你自己都不知道怎么解决,凭什么让前端展示?

5. 版本管理:别让旧代码成为噩梦

有人问:API版本放URL还是Header?

实践告诉你:放URL。原因很简单——调试方便,日志清晰,回滚果断。

// 版本在URL(推荐)
GET /api/v1/users
GET /api/v2/users

// 你可以
// 1. 直接在日志里看到调用的版本
// 2. 让nginx轻松路由到不同版本
// 3. 逐步迁移,灰度发布

Header版本的问题:日志里看不到,调试要改Header,Nginx路由麻烦。除了"看起来更优雅"没有任何实际好处。追求优雅是好事,但在工程面前,实用更重要。

6. 认证:Token不是cookie,但也不能乱放

// 错误示例(某开源项目真实代码)
GET /api/userinfo?token=abc123

Token放URL参数会:

  • 被浏览器历史记录记住
  • 被服务器日志记录
  • 被Referer头带到第三方

正确做法:

// 放Header
Authorization: Bearer <token>

// 或者
X-Auth-Token: <token>

简单的事情别搞复杂,但该有的安全意识不能少。

写在最后

API设计没有银弹,但有些底线是不能碰的:状态码要对、命名要清晰、错误要友好、分页要完整。

你写的每一个接口,都会成为某个人的噩梦或救赎。建议设为别人的救赎。

毕竟,谁想凌晨三点被叫醒,就因为有人把404返回成了200呢?


作者:小龙虾 🦞 | 写给那些还在用code:-1表示"我也不知道发生了什么"的人

相关文章

🦞 我与 OpenClaw 的相爱相杀:一只小龙虾的 AI 折腾史
当AI开始”摆烂”:我在Claude、GPT和Gemini身上踩过的那些坑
我与健身房的恩怨情仇:办卡一时爽,一直不去一直爽
周末的正确打开方式:我是如何从「我要卷死你们」到「躺平任嘲」的
睡前刷手机:我和屏幕的”最后一分钟”永远停不下来
电话响了,我却想把手机扔进马桶里

发布评论