为什么你的API总是被人吐槽?一次把REST设计说清楚

2026-04-14 18 0

做后端开发这么多年,听过最多的抱怨就是:「这API谁设计的,脑子进水了吧?」然后一问,return的是200但业务失败了,参数命名全是拼音缩写,文档写的是「参数见下方」然后下方什么都没有。

今天不整虚的,直接聊REST API设计中那些容易翻车但又没人正经教的东西。都是我踩过的坑,看完能少挨骂。

状态码不是随便写的

很多人以为HTTP状态码就是个装饰品,200万能,出了事先返回200再说。这种做法跟考试作弊交白卷然后在卷子画个笑脸一样——老师看了想打人。

说几个最常见的场景:

  • 创建资源成功 → 201 Created,顺便把新资源的URL放Location头里
  • 删除成功但本来就不存在 → 204 No Content,别返回404因为你确实「处理了」请求
  • 请求格式对了但业务逻辑不对 → 422 Unprocessable Entity,别塞进200里假装天下太平
  • 认证失败 → 401,没权限是403,分清楚

基本原则:能用状态码说清楚的事,别用返回体里的code字段绕弯子。你多写一个字段,前端就要多判一个字段,烦不烦啊。

分页:这是个考验人品的地方

分页看似简单,但90%的实现都有问题。最经典的:「page=1&size=20」然后告诉你总共有999条,这是让人算总页数玩呢?

推荐用cursor-based pagination(游标分页),理由:

// 请求
GET /api/v1/articles?cursor=eyJpZCI6MTIzfQ&limit=20

// 返回
{
  "data": [...],
  "pagination": {
    "next_cursor": "eyJpZCI6MTQzfQ",
    "has_more": true
  }
}

好处是什么?数据动态变化时不会重复或跳过。比如你翻到第三页,中间有人新插入了一条记录,offset分页会让你要么看到重复的,要么跳过的。cursor分页不存在这个问题。

什么时候用offset分页?后台管理列表需要跳页的场景可以用,但得同时返回total_count让人知道总共有多少页。

字段命名:保持一致就是最好的文档

这个问题我见过最离谱的是:一个项目里同时出现 created_at、createTime、create_at、add_time 四种写法,问就是「历史遗留问题」。

定个标准就完事了,推荐遵循JSON API规范:

  • 蛇形命名:create_at、article_title
  • 时间戳统一用毫秒级Unix时间戳,别用字符串日期
  • 布尔值加is/has/can前缀:is_active、has_permission、can_edit

还有一个很多人忽略的:分清input和output的字段名。比如创建文章的API,接收的是title和content,但返回的要包含id、created_at、author这些服务端生成的东西。别让前端去猜你返回了啥字段。

错误处理:说人话

错误返回里最让人想砸键盘的是这种:

{
  "code": -1,
  "msg": "操作失败",
  "data": null
}
}

「操作失败」——废话,我知道操作失败了,我问的是为啥失败。这种错误返回等于没返回。

好的错误结构应该是这样:

{
  "error": {
    "code": "ARTICLE_NOT_FOUND",
    "message": "请求的文章不存在或已被删除",
    "details": {
      "article_id": 12345
    }
  }
}
}

code用业务层面的错误码,方便前端做switch-case判断;message是给人看的,说清楚什么情况;details是技术上下文,帮助排查问题。

还有个关键点:不要暴露内部实现细节到错误信息里。你数据库连接失败了,错误信息写「SQL执行失败: Connection refused」是方便黑客还是方便调试?对外只说「服务暂时不可用」,日志里记详细的信息就行了。

版本管理:别搞成考古现场

最常见的两种版本策略:URL里写版本号(/api/v1/),或者用Header(Accept: application/vnd.api+json; version=1)。

我的建议是:用URL版本,简单直接。理由:

  • 调试方便,直接复制URL就能分享给别人
  • CDN和网关更容易处理
  • 所有HTTP工具原生支持,不需要特殊Header配置

版本升级的节奏:不要轻易破坏性变更。加了新字段算小事儿,换了必填参数或者改了返回结构这种,才是让前端原地爆炸的操作。非改不可的话,先把新版本跑一段时间,等旧版本流量清零了再下掉。

写在最后

API设计这事,说难听点就是「别人骂你的时候才知道做得好不好」。所以别闭门造车,写完了让前端过来挑刺,听取意见,迭代几轮自然就好了。

当然,最好还是别等人骂了再做对。


题图:Photo by Annie Spratt on Unsplash

相关文章

写API一时爽,调试火葬场:我踩过的那些坑
你的Go服务正在偷偷”漏”协程,而你还浑然不知
别再把API设计成一坨屎了:RESTful设计避坑指南
老板问我为什么查询慢,我甩给他一个 EXPLAIN,结果他闭嘴了
为什么你的API总是被人骂?一位老油条的掏心窝子经验
你的HTTP客户端正在悄悄偷走你的性能:那些连接池不会告诉你的事

发布评论