引言
大家好,我是码农刚子。在过去几年里,GraphQL、gRPC、tRPC 等技术层出不穷,但在大多数业务系统中,REST 仍然是最常见、最容易落地、最容易协作的接口风格。原因很简单:REST 足够朴素——它基于 HTTP,不要求客户端和服务端共享复杂协议,前端、移动端、后端、测试、运维都能理解它。
但也正因为 REST 看起来简单,很多项目最后会写成“披着 HTTP 外衣的随意 RPC”:所有接口都是 POST /doSomething,状态码永远是 200,错误都塞在 message 里。短期能跑,长期则难以维护。
本文将从 RESTful 的核心原则出发,系统讲解 URI 设计、HTTP 方法规范、状态码使用、版本控制、安全认证等关键环节,帮助开发者构建规范、可维护的 RESTful API。
一、REST 的核心原则
REST(Representational State Transfer,表述性状态转移)由 Roy Fielding 博士在其论文中提出,其核心在于六个架构约束:
- 客户端-服务器架构:客户端与服务器各自独立开发与演进
- 无状态性:每个请求必须包含所有必要信息,服务器不保存客户端状态
- 可缓存性:支持 HTTP 缓存机制,提升性能
- 统一接口:通过标准化的 HTTP 方法操作资源
- 分层系统:支持代理、网关等中间层,提升可扩展性
- 按需代码(可选):服务器可向客户端返回可执行代码
其中,资源导向和无状态通信是 RESTful API 设计中最核心的两个原则。
二、URI 设计:让资源一目了然
2.1 使用名词复数形式
RESTful API 的核心在于将系统功能抽象为可操作的资源(Resources),每个资源通过唯一 URI 标识。资源名称应使用名词复数形式,避免动词。
✅ 正确:
GET /users # 获取用户列表
GET /users/123 # 获取单个用户
POST /users # 创建用户
PUT /users/123 # 更新用户
DELETE /users/123 # 删除用户
❌ 错误:
GET /getUserList
POST /createUser
POST /updateUser
2.2 层级结构表达关联关系
使用 /resource/{id}/subresource 表示资源间的关联:
GET /users/123/orders # 获取用户 123 的所有订单
GET /users/123/orders/456 # 获取用户 123 的订单 456
2.3 查询参数用于过滤、排序和分页
复杂的查询条件不应嵌入 URI 路径,而应使用查询参数:
GET /products?category=electronics&page=2&size=20&sort=price,desc
2.4 命名规范要点
- 使用小写字母,单词间用**连字符(-)**分隔
- 避免使用下划线(_)或驼峰命名法
- 保持命名简洁且一致
三、HTTP 方法:用对动词,让接口自解释
RESTful API 通过标准 HTTP 方法明确操作类型。以下是各方法的语义规范:

幂等性是指:同一个请求执行一次和执行多次,最终结果一致。例如 DELETE /orders/1001 执行一次是删除订单,再执行一次仍然是“订单不存在”,最终状态没有变化,因此它是幂等的。而 POST /orders 每执行一次都可能创建一个新订单,所以不是幂等的。
实践建议:
- 避免用 POST 替代 PUT/DELETE,这会破坏语义清晰性
- 部分更新优先使用 PATCH 而非 PUT
- 批量操作可通过
POST /api/batch实现,但需明确文档说明
四、状态码:让 HTTP 协议发挥应有作用
很多系统喜欢这样返回:
{
"code": 500,
"message": "server error",
"data": null
}
但 HTTP 状态码却永远是 200 OK。这种做法对调试、网关、监控、SDK 都不友好。
更合理的方式是:让 HTTP 状态码表达协议层结果,让响应 body 表达业务细节。
4.1 常用状态码分类

关键原则:永远不要在参数错误时返回 500,也不要在成功时返回 200 但 body 里塞个 code: 500。
五、响应体设计
5.1 成功响应
{
"data": {
"id": 123,
"username": "coder log",
"email": "manonggangzi@coderlog.net"
},
"meta": {
"timestamp": "2026-06-29T12:00:00Z"
}
}
5.2 错误响应
{
"error": {
"code": "INVALID_INPUT",
"message": "Email format is invalid",
"details": [
{
"field": "email",
"issue": "must be a valid email address"
}
]
}
}
- 成功响应包含
data和meta字段 - 错误响应采用统一错误码体系,包含详细的错误定位信息
- 字段命名建议采用小写蛇形命名法(如
user_id)
六、版本控制:让 API 平滑演进
API 会随着业务发展而演进,新版本必须与旧版本共存,以防止破坏现有的集成。
6.1 常见版本控制策略
| 策略 | 示例 | 优缺点 |
|---|---|---|
| URI 路径 | /v1/users、/v2/users |
最直观,易于理解和调试 |
| 请求头 | Accept: application/vnd.api+json;version=1 |
保持 URI 干净,但对客户端不够直观 |
| 查询参数 | /users?version=1 |
简单但不符合 REST 语义 |
推荐使用 URI 路径方式,因为其最直观,且便于通过浏览器、curl 等工具直接测试。
6.2 语义化版本
- 主版本号(v1 → v2):破坏性变更
- 次版本号:向后兼容的功能增强
- 补丁版本号:向后兼容的错误修复
七、安全认证
7.1 认证方案
现代 API 已淘汰简单的 HTTP Basic 认证,普遍采用:
- JWT(JSON Web Token) :无状态、可扩展,适合分布式系统
- OAuth 2.0:适合第三方授权场景
7.2 最佳实践
- Token 通过
Authorization: Bearer <token>Header 传递,严禁放在 URL 参数中(会被记录在服务器日志和浏览器历史中) - 设置严格的过期时间(访问令牌建议不超过 1 小时)
- 永远不要在 JWT payload 中存储敏感数据
- 敏感接口必须实现认证,关键操作(如支付、删除)需增加二次确认机制
- 始终使用 HTTPS 加密通信
八、分页、过滤与排序
对于可能返回大量数据的集合接口,应从一开始就支持服务端分页。
8.1 分页参数
GET /orders?page=2&size=20
或使用 limit/offset 方式:
GET /orders?limit=20&offset=40
8.2 过滤与排序
GET /orders?status=paid&createdSince=2026-01-01&sort=-createdAt
- 过滤:
field=value形式,如status=paid - 排序:
sort=field升序,sort=-field降序
九、API 文档
9.1 使用 OpenAPI 规范
OpenAPI 规范(原 Swagger)是 RESTful API 文档的行业标准。一个标准的 OpenAPI 文档应包含:
- 接口路径与 HTTP 方法
- 请求/响应参数示例
- 状态码说明
- 调用频率限制
- 示例代码(cURL、Python、JavaScript 等)
9.2 文档的价值
采用 OpenAPI 规范可使接口联调周期缩短 40% 以上。通过 Swagger UI 等工具,可以将 YAML/JSON 格式的规范文件渲染为可交互的 Web 文档,前端、后端、测试人员可以实时校验接口设计。
十、常见设计陷阱与避坑指南
❌ 陷阱一:所有接口都用 POST
POST /getOrderList
POST /createOrder
POST /updateOrderStatus
POST /deleteOrder
问题:HTTP Method 失去语义,接口少时问题不大,一旦系统变复杂,命名会越来越混乱。
正确做法:用 HTTP 方法表达动作,用 URI 表达资源。
❌ 陷阱二:状态码永远 200
问题:对调试、网关、监控、缓存都不友好。
正确做法:HTTP 状态码表达协议层结果,响应 body 表达业务细节。
❌ 陷阱三:业务动作硬拧成资源操作
PUT /orders/1001 # 试图用 PUT 完成“支付订单”
问题:有些动作很难完全资源化。
正确做法:将动作建模为子资源:
POST /orders/1001/payment
POST /orders/1001/cancellation
POST /approval-tasks/2001/submission
工程设计要讲语义,也要讲可读性,不要为了追求形式上的 REST 而牺牲可读性。
结语
REST 之所以经久不衰,不是因为它在技术上最前沿,而是因为它足够朴素、足够通用。一个好的 RESTful API 设计,不需要复杂的框架和工具链——一个接口文档写清楚 URL、Method、参数、返回值和状态码,团队就能顺畅协作。
REST 之稳,不在复杂,而在朴素与坚持。遵循本文梳理的设计原则和最佳实践,相信你能构建出清晰、一致、易于维护的 RESTful API。