为什么你的API总被人骂?10年踩坑总结

2026-03-28 6 0

做后端开发这些年,我见过太多API设计得让人想砸键盘。不是接口慢得像爬虫,就是返回结构乱得让人怀疑人生。今天把这10年踩过的坑整理一下,希望你们别再重蹈覆辙。

1. 命名:让人看懂比显得自己牛更重要

见过最离谱的接口名:getNttInfoByCond。ntt是什么?condition又是什么?猜去吧。

好的命名应该是自解释的:

// 烂名字
getNttInfoByCond
fuzzyQueryUser
updateRec

// 好名字
getNotificationByCondition  // 虽然还是模糊,但至少能猜
searchUsers                 // 清晰
updateRecommendation        // 全拼,不猜

// 最佳实践
getUserNotifications        // 名词复数,资源导向
searchArticlesByTag          // 动作+资源+过滤条件

记住:代码是写给人看的,API是给其他开发者用的。让他们少猜一次,你就少挨骂一次。

2. HTTP方法:用对了吗?

这个问题在团队里能吵三天。

// 很多人这么干
POST /api/updateUser          // 更新用POST?
POST /api/deleteUser?id=123  // 删除也用POST?
GET /api/saveArticle         // 保存用GET??

// 标准做法
PUT /api/users/123           // 更新用户
DELETE /api/users/123        // 删除用户
POST /api/articles           // 创建文章
GET /api/articles            // 查询文章列表

几个原则:

  • GET:只读,不修改任何东西
  • POST:创建资源
  • PUT:完整更新(替换)
  • PATCH:部分更新
  • DELETE:删除

如果你的接口不遵循这些,其他开发者接的时候心里一定是骂娘的。

3. 状态码:别总是200 OK

有些接口永远返回200,但code字段是1表示失败。这是初级的做法,但不是好做法。

// 糟糕:HTTP 200 + 业务code
{
  "code": 1,
  "message": "用户不存在",
  "data": null
}

// 好做法:正确的HTTP状态码
HTTP 404 Not Found
{
  "error": "user_not_found",
  "message": "用户不存在"
}

// 认证失败
HTTP 401 Unauthorized
{
  "error": "invalid_token",
  "message": "Token已过期"
}

// 参数错误
HTTP 400 Bad Request
{
  "error": "validation_failed",
  "message": "手机号格式不正确",
  "fields": ["phone"]
}

标准HTTP状态码是语言,用对了事半功倍。

4. 分页:Page还是Offset?

这是另一个能引发团队血案的话题。

// OFFSET方式(简单但有性能问题)
GET /api/users?page=1&page_size=20

// Cursor方式(性能好,但只支持单向)
GET /api/users?cursor=xxx&limit=20

// 时间范围方式(适合日志类数据)
GET /api/orders?start_time=2025-01-01&end_time=2025-01-31

数据量小用Page,数据量大用Cursor。简单粗暴但有效。

5. 版本管理:早做比晚做好

没做版本管理的API,最后都会变成噩梦。

// 路径版本(最常见)
/api/v1/users
/api/v2/users

// Header方式
API-Version: 2024-01-01

// Query参数(不推荐)
/api/users?version=2

路径版本最直观,但要注意:v1维护成本不低,能不维护就不维护,推动上游尽快升级才是正道。

6. 错误信息:给开发者看的,不是给用户看的

错误信息要写给接手你接口的开发者看,不是给终端用户看。

// 烂错误信息
{"error": "操作失败"}
{"error": "参数错误"}

// 好的错误信息
{
  "error": "validation_error",
  "message": "请求参数验证失败",
  "details": {
    "field": "email",
    "reason": "邮箱格式不正确",
    "received_value": "abc"
  }
}

// 更进一步:给出文档链接
{
  "error": "resource_not_found",
  "message": "文章不存在",
  "documentation_url": "https://api.example.com/docs/errors#article-not-found"
}

7. 性能:N+1是每个后端人的噩梦

最常见的性能杀手:

// 典型N+1
GET /api/users/123
// 返回
{
  "name": "张三",
  "posts": [
    { "id": 1, "title": "文章1", "author_id": 456 },  // 456是谁?
    { "id": 2, "title": "文章2", "author_id": 789 }   // 789又是谁?
  ]
}

// 解决方案1:嵌套返回
GET /api/users/123?include=posts.author

// 解决方案2:分开调用,但用缓存
// 第一次调用后,author信息被缓存,后续调用不查库

原则:一次能查完的,不要分多次。除非你打算以后做微服务拆分。

8. 安全:基础中的基础

// CORS配置(开发环境图方便,生产环境要严谨)
// 烂:
Access-Control-Allow-Origin: *

// 好:
Access-Control-Allow-Origin: https://yourdomain.com

// 速率限制(保护你的服务)
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640000000

// 敏感操作要审计
POST /api/orders (应该记录操作日志)
POST /api/refunds (更应该记录)

总结

API设计没有绝对的标准,但有几个通用原则:

  1. 命名即文档:名字起好,注释少一半
  2. 遵循HTTP语义:方法对、状态码对
  3. 错误信息要有用:让调用者知道错在哪
  4. 性能要考虑:N+1是万恶之源
  5. 安全是底线:别等到被刷才想起来加限制

好的API设计不会让你出名,但会让你的同事少骂你。祝各位的接口都稳稳当当,调用者都心平气和。

相关文章

为什么你的API总被人骂?10年踩坑总结
我把AI调教了三个月,发现了一个反直觉的真相
那些年我们踩过的HTTP超时坑:一次线上事故的深度复盘
写接口这事,能别那么随意吗?后端API设计的七个血坑
RESTful API设计:那些年我们一起踩过的坑
OpenClaw 体验报告:论一只AI小龙虾是如何被自己的工具折腾疯的

发布评论