我见过最烂的 API 设计,连 PM 都看不下去了

2026-08-12 7 0

我见过最烂的 API 设计,连 PM 都看不下去了

做后端开发这些年,看过的 API 比你看过的网络小说还多。说实话,大部分都是垃圾——不是功能实现得差,而是接口设计得让人想打人。

今天不整虚的,直接聊几个真实项目中见过的 API 设计毛病,顺便给点靠谱的改进思路。信不信由你,但这些都是血泪教训。

一、你的 URL 结构暴露了你的人品

先看几个我亲眼见过的骚操作:

GET /getUserById?id=123
POST /createNewUser
PUT /updateUserInfo
DELETE /deleteUser

看到这种 API,我内心是崩溃的。这不叫 REST,这叫"我用 HTTP 动词当装饰"。

RESTful API 的 URL 应该是名词,不是动词。动词是 HTTP 方法该干的事。正确姿势:

GET    /users/123        # 获取用户
POST   /users            # 创建用户
PUT    /users/123        # 更新用户
DELETE /users/123        # 删除用户

简单、清晰、一目了然。别人拿到这个 API 文档,不用猜就知道干嘛的。

好的 URL 结构是自我解释的,不需要注释。

二、状态码用错,比写错别字还丢人

很多人写 API 返回数据长这样:

{
  "code": 200,
  "message": "success",
  "data": { ... }
}

然后不管出啥错都返回 200 OK。这不是误导前端吗?200 意味着"一切正常",你数据库崩了也返回 200,前端还以为一切顺利呢。

HTTP 状态码是干嘛用的?就是让调用方不用解析你的 body 就能知道请求结果。好好用:

  • 200 - 成功(GET、PUT、PATCH、DELETE 操作成功)
  • 201 - 资源创建成功(POST 创建了新资源)
  • 400 - 请求参数有问题(前端别甩锅了,是你 API 接收格式不对)
  • 401 - 没登录或 Token 过期(请重新登录)
  • 403 - 登录了但没权限(你不是 VIP,不能访问这个资源)
  • 404 - 资源不存在(你找的那玩意儿早没了)
  • 429 - 请求太频繁(限流了,别疯狂刷)
  • 500 - 服务器炸了(我们的锅,赔礼道歉中)

前端拿到 401 就知道要跳转登录页,拿到 403 就知道要提示权限不足,根本不用解析你的 body。这才叫前后端配合。

三、分页参数瞎写,数据库背锅

这种分页参数你见过吗?

GET /users?page=1&limit=20&sort=created_at&order=desc&search=关键词

看起来挺标准?问题在于 sort 和 order 这俩字段。

sort 参数直接传字段名,假设有个字段叫 user_name,前端直接传 sort=user_name。万一这是个 SQL 注入漏洞呢?或者字段名拼错了呢?

更好的做法:

GET /users?page=1&limit=20&sort_by=created_at&order=desc

后端做一个白名单校验,只允许特定的字段名参与排序。数据库字段是内部实现,不应该暴露给外部。

API 是对外的合同,合同里的字段名应该稳定、可预期、不暴露实现细节。

四、返回结构不统一,前端想骂人

看这个场景:

# 第一次请求
GET /users/123
{
  "id": 123,
  "name": "张三",
  "email": "zhangsan@example.com"
}

# 第二次请求  
GET /users
[
  {"id": 123, "name": "张三", ...},
  {"id": 124, "name": "李四", ...}
]

单个资源和资源列表,返回结构不一样?前端得多写多少判断代码?列表接口返回一个包装对象会死吗?

统一返回格式是基本礼仪:

{
  "code": 0,
  "message": "success",
  "data": {
    "items": [...],
    "total": 100,
    "page": 1,
    "page_size": 20
  }
}

不管查一个还是查一百个,结构都一样。前端拿到 data.items 就能直接渲染,不用先判断 data 是数组还是对象。

五、版本号乱飞,升级一次改半死

没做版本控制之前:

/api/getUserInfo
/api/queryUser
/api/fetchUserData

三年后,这三个接口分别由三个离职的同事维护,没人知道它们有什么区别。这就是技术债务,利滚利的那种。

RESTful 风格推荐在 URL 里带版本号:

/api/v1/users
/api/v2/users

v1 和 v2 可以同时跑一段时间,让前端慢慢迁移。v2 接口改了响应结构,v1 用户不受影响。平滑过渡,不伤感情。

六、缺乏文档等于没有 API

很多人写完代码就交付,文档?不存在的。调用方自己猜去吧,猜错了算你倒霉。

说真的,给你的 API 写个文档不丢人。至少包含:

  • 接口描述(这个 API 干什么用)
  • 请求方法和 URL
  • 请求参数说明(类型、是否必填、取值范围)
  • 响应结构和示例
  • 错误码说明
  • 调用示例(cURL、HTTP、Python 都来一个)

用 Swagger/OpenAPI 规范写,直接生成交互式文档。调用方点点鼠标就能测试,比你发一百页 Word 文档强一万倍。

写在最后

API 设计这事,说难听点,暴露了一个程序员的基本素养。是只想实现功能,还是真的在为调用方考虑?是有全局观,还是写完就跑?

好的 API 设计有这几个特点:

  • 看 URL 就能猜出功能
  • 看状态码就知道结果
  • 看文档就能调用,不需要电话沟通
  • 改实现不影响调用方(你改数据库字段,别人不用动)

下次写 API 之前,先问自己一个问题:如果别人要用我这个 API,我会觉得丢脸吗?

如果会,那就改。如果不会,那恭喜你,你是个合格的后端工程师了。

(完)

相关文章

你的SQL执行计划:95%的程序员都没看懂那张该死的表格
你的接口慢成狗,可能只是因为缓存没整明白
数据库连接池:你好好的应用,怎么就开始抽风了?
面试能背八股文,生产却还在全表扫描:SQL优化的八个反直觉真相
RESTful API 设计翻车现场:那些年我们一起写过的烂接口
SQL优化这条路,走过的人都说”太难了”

发布评论