为什么你的API总被吐槽?血泪教训总结的RESTful设计避坑指南

2026-04-29 18 0

为什么你的API总被吐槽?血泪教训总结的RESTful设计避坑指南

做后端开发这么多年,我见过太多「能跑就行」的API,也见过太多因为API设计烂而被喷得体无完肤的项目。更见过产品经理拿着接口文档一脸懵逼,开发自己过两天再看自己写的代码也懵的情况。

今天不整虚的,直接上硬菜——我从无数次踩坑中总结出来的RESTful API设计避坑指南。全文干货,建议先收藏再看。

一、先搞清楚什么是真正的REST

很多人在简历上写「精通RESTful API设计」,结果一问他HTTP方法有哪些,都只能说个GET和POST。兄弟,你这不叫精通,这叫「听说过」。

REST架构风格的核心就六条原则:客户端-服务器、无状态、缓存、统一接口、分层系统、按需代码。其中最容易被忽略的就是「统一接口」——你的API应该长什么样,其实是有规范的。

资源(Resource)是核心,所有东西都是资源。URI是资源的地址,HTTP方法是操作资源的方式。

举个经典错误:

// 错误示范
POST /api/getUser
POST /api/deleteUser
POST /api/updateUser

// 正确姿势
GET /api/users/{id}
DELETE /api/users/{id}
PATCH /api/users/{id}

看出来了吗?同一个资源,不同操作,用不同的HTTP方法,URI保持一致。这就是REST的精髓。

二、URI设计:别把API写成作文

见过最离谱的API是这个:

/api/v1/queryUserInfoByIdAndReturnJsonFormat
/api/v1/getAllTheUsersWhoHaveOrdersInTheLast30Days

我怀疑写这个API的兄弟是故意的,就是为了让自己不可替代。

URI设计记住这几个原则:

1. 用名词,不用动词

资源是名词,操作是HTTP方法。下面这个表格记好了:

操作 HTTP方法 示例
获取资源 GET GET /users
获取单个资源 GET GET /users/123
创建资源 POST POST /users
更新资源 PUT/PATCH PUT /users/123
删除资源 DELETE DELETE /users/123

2. 层级结构要合理

// 用户123的订单
GET /users/123/orders

// 订单456的商品
GET /orders/456/items

层级关系要符合业务逻辑,不要嵌套太深。建议最多三层,再深就考虑用查询参数。

3. 查询参数用来过滤,别用来做操作

// 正确:筛选是查询参数
GET /users?status=active&role=admin

// 错误:把操作放到了查询参数里
GET /api/getUsersByStatus?status=active

三、状态码:别总是200 OK

有些同学的API,返回永远都是200,哪怕是删除了不存在的数据也200。这是掩耳盗铃。

HTTP状态码是API的语言,要用它正确表达含义:

2xx 成功系列

  • 200 OK:请求成功,返回内容
  • 201 Created:资源创建成功,响应头带Location
  • 204 No Content:成功但无返回内容(常见于DELETE)

4xx 客户端错误系列

  • 400 Bad Request:请求参数有问题
  • 401 Unauthorized:未认证(没登录)
  • 403 Forbidden:已认证但没权限
  • 404 Not Found:资源不存在
  • 409 Conflict:资源冲突(如重复创建)
  • 422 Unprocessable Entity:请求格式对但语义错

5xx 服务端错误系列

这个简单,出了5xx就是后端背锅。别解释,直接查日志修bug。

一个血泪教训:千万别为了省事,所有错误都返回400加一个「系统繁忙」的消息。客户端需要知道具体哪里错了,才能正确处理。

四、请求体与响应体:格式化是基本礼仪

JSON已经是最通用的格式了,别再搞什么XML、Custom YAML。除非你有特殊理由。

请求体规范

{
  "username": "zhangsan",
  "email": "zhangsan@example.com",
  "age": 28
}

字段命名统一用camelCasesnake_case,全项目保持一致。切忌一会儿驼峰一会儿下划线。

响应体规范

统一响应结构,这是最重要的规范之一:

{
  "code": 0,
  "message": "success",
  "data": {
    "id": 123,
    "username": "zhangsan"
  }
}

或者:

{
  "success": true,
  "data": {},
  "error": null
}

选一种,全项目统一。别一个模块用code,一个模块用success,调用方会疯的。

分页响应

{
  "data": [],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "total": 100,
    "totalPages": 5
  }
}

分页参数用page+pageSize或者offset+limit,选一种。但一定要返回总数,这是前端分页组件的基本需求。

五、版本管理:给自己留条活路

接口一旦发布,就是合约。改它代价很大。所以从一开始就规划好版本策略。

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

版本号放在URL路径里,不要放Header里。放在Header里是给自己找麻烦,前端同学会骂你。

什么时候升版本?

  • 删除或重命名字段
  • 改变字段类型
  • 改变字段含义
  • 移除或废弃端点

什么时候不改版本?

  • 新增字段(向后兼容)
  • 新增API端点
  • 性能优化

六、安全:这事儿不能省

认证与授权

认证和授权是两码事:

  • 认证(Authentication):你是谁?
  • 授权(Authorization):你能干什么?

API认证用JWT或者OAuth2,别再明文传输密码或者把token放URL里。

// 正确:token放Header
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

// 错误:token放URL(会被浏览器历史记录、日志等记录)
GET /api/users?token=eyJhbGciOiJIUzI1NiIs...

参数校验

永远不要相信客户端传来的数据。每一个参数都要校验:

// 参数校验伪代码
if (!id || typeof id !== number || id <= 0) {
  return res.status(400).json({
    code: 400,
    message: id参数无效
  });
}

限流

你的API对外开放,就要做限流。不然被人一个for循环请求打挂,别怪我没提醒你。

// 响应头带限流信息
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640000000

七、文档:这活儿值十万

我见过太多「代码即文档」的项目,注释都没几行,更别说接口文档了。

接口文档要包含:

  • 端点描述
  • 请求参数(类型、是否必填、取值范围)
  • 响应结构(每个字段的含义)
  • 错误码说明
  • 请求示例
  • 响应示例

工具推荐:Swagger/OpenAPI、Apifox、Postman。选一个用起来,团队协作效率能提升一倍。

最烂的文档是「接口文档请看代码」。说这话的人,我怀疑他自己是唯一能看懂代码的人。

总结

API设计是后端开发的基本功,设计得好,调用方爽,自己后续维护也爽。设计得烂,那就是给自己埋雷,指不定哪天就炸。

记住这几个核心要点:

  • 资源导向,名词复数形式
  • 正确使用HTTP方法
  • 合理使用状态码
  • 统一响应结构
  • 做好版本规划
  • 安全措施不能省
  • 文档要写,而且要写好

代码写得好是基本功,API设计得好是加分项。从今天开始,重新审视一下你手上的接口,有坑的赶紧填,别等到被人指着鼻子骂再来改。

有问题欢迎留言,我看到了会回。

相关文章

AI圈最近都在玩什么?OpenClaw这些骚操作把我看傻了
写API这事儿:为毛你的接口总是被吐槽?
你的API为什么慢?我花了一周排查,结果是个空格惹的祸
微服务:看上去很美,用起来很贵
一次诡异的数据库死锁,帮你彻底搞懂事务隔离级别
WebSocket连接总是断?可能是你打开方式不对

发布评论