RESTful API 设计翻车现场:那些年我们踩过的坑

2026-10-12 17 0

RESTful API 设计翻车现场:那些年我们踩过的坑

做后端开发这么多年,我发现一个有趣的现象:写 API 的时候,每个人都觉得自己的设计很优雅。但半年后回看代码,往往只想穿越回去掐死当时的自己。今天来聊聊我见过的那些 API 设计翻车现场,保证你看完会说"这不就是我吗"。

一、HTTP 状态码:别再用 200 塞一切了

我见过最离谱的 API 是这样的:

// 不管成功还是失败,统统返回 200
{
  "code": 0,  // 0表示成功,其他表示失败
  "message": "操作成功",
  "data": null
}

兄弟,你这是在 HTTP 协议上又封装了一层协议啊!那 HTTP 状态码是用来干嘛的?装饰用的吗?

更可怕的是,这种设计会导致你的接口文档变得像悬疑小说:

// 这个接口可能返回 200 但实际出错了
// 需要看 code 字段才知道真相
// 你是在玩大家来找茬吗?

正确姿势:

// 成功
200 OK
{"id": 123, "name": "小龙虾"}

// 客户端错误
400 Bad Request
{"error": "validation_failed", "message": "手机号格式不对"}

401 Unauthorized
{"error": "unauthorized", "message": "token过期了"}

404 Not Found
{"error": "not_found", "message": "这个用户不存在"}

500 Internal Server Error
{"error": "internal_error", "message": "服务器抽风了"}

二、命名:你的接口名是认真的吗?

我见过最离谱的接口命名包括:

// 方法名是 getById,但实际是删除操作
POST /api/user/getById  // 这是删除!

// 功能重复的两个接口
POST /api/user/create
POST /api/user/add  // 有什么区别??

// 中英混杂
GET /api/user/getUserInfoById  // 你是怕程序员看不懂吗

RESTful 的核心是"所见即所得":

// 资源 + 操作 = 接口名
GET    /users      // 获取用户列表
GET    /users/123  // 获取单个用户
POST   /users      // 创建用户
PUT    /users/123  // 更新用户(完整)
PATCH  /users/123  // 更新用户(部分)
DELETE /users/123  // 删除用户

三、分页:这是一个哲学问题

翻车现场一:

// 返回所有数据,让前端自己截
GET /api/users
// 返回: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...无限延长]

这接口一旦用户多了,就是一场 DDoS 攻击。只不过攻击来源是你自己的用户。

翻车现场二:

// offset 太大直接爆炸
GET /api/users?offset=1000000&limit=10
// 数据库: 全表扫描...

正确的分页方式:

// 1. 游标分页(性能好)
GET /api/users?cursor=eyJpZCI6MTIzfQ&limit=10
// 返回:
{
  "data": [...],
  "next_cursor": "eyJpZCI6MTMzfQ",
  "has_more": true
}

// 2. 如果数据量确实小,用 offset 也行,但记得加 limit 上限
GET /api/users?offset=0&limit=20  // limit 最大 100

四、版本管理:没有版本的 API 是不负责任的 API

我见过最勇敢的开发者是这样设计的:

// 不管了,硬上!
GET /api/users

// 半年后...
// 需要加 v2 功能了
// 怎么办?
// 创建新接口!
GET /api/usersV2

// 又过了半年...
// 有了 usersV2,为什么不用?来个大杂烩
GET /api/usersV3  // 包含 V1 的核心 + V2 的功能 + 一些新东西

// 维护者:我是谁?我在哪?这个接口是干嘛的?

版本管理的正确打开方式:

// 路径版本(最直观)
GET /api/v1/users
GET /api/v2/users

// Header 版本
GET /api/users
Accept: application/vnd.api.v2+json

// 建议用路径版本,前端同学会感谢你的

五、错误信息:别只告诉前端"错了",要说清楚哪错了

最常见的错误返回:

// 这样写等于没写
{
  "message": "操作失败"
}

// 前端:哪里失败了?为什么失败了?我该怎么办?
// 后端:我也不知道,反正就是失败了

好的错误信息应该像这样:

{
  "error": "validation_error",
  "message": "参数校验失败",
  "details": [
    {
      "field": "email",
      "message": "邮箱格式不正确",
      "value": "this_is_not_email"
    },
    {
      "field": "age",
      "message": "年龄必须大于0",
      "value": -5
    }
  ],
  "request_id": "req_abc123"  // 用于排查问题的请求ID
}

六、写在最后

API 设计这件事,说难听点就是"一次写错,半年买单"。每次你偷懒用模糊的命名、随意的状态码、敷衍的错误信息,都是在给未来的自己和同事挖坑。

好的 API 设计其实就一个原则:让你的接口像一篇说明文,清清楚楚,明明白白。调用者不需要猜,不需要看源码,不需要问你"这个接口到底是怎么用的"。

记住:你现在写的代码,就是半年后你骂的对象。省点心,好好写。🙏


P.S. 如果你觉得这篇文章有用,说明你身边可能有个正在写烂 API 的同事。转发给他,救人一命,胜造七级浮屠。

相关文章

还在为部署AI工具熬夜?找小龙虾,一键搞定!
还在为部署AI工具熬夜?找小龙虾,一键搞定!
RESTful API 设计翻车现场:那些年我们踩过的坑
AI Agent浪潮来袭:我试了市面上最火的五个,差距大得离谱
你以为缓存只会被击穿和穿透?击穿才是那个最隐蔽的杀手
你的JWT实现,我敢说80%的后端都踩过这些坑

发布评论