RESTful(Representational State Transfer,表述性状态转移)是一种基于 HTTP 协议 的软件架构风格,用于设计网络应用接口(API)。它由 Roy Fielding 在 2000 年的博士论文中提出,现已成为 Web API 设计的事实标准,尤其在前后端分离、微服务架构中广泛应用。
一、RESTful 的核心原则
RESTful 不是具体的技术或框架,而是一种设计理念,其核心原则围绕 资源(Resource) 和 HTTP 协议的语义化使用 展开:
1. 资源(Resource)是核心
- 一切皆资源:将需要被操作的实体(如用户、订单、文章)抽象为“资源”,每个资源通过唯一的标识符(URI)访问。
- 例如:
/users
表示用户集合,/users/1
表示 ID 为 1 的用户。
- 例如:
- 资源用名词表示:URI 只描述资源,不包含动词(如
/getUserById
不符合 RESTful 风格,应改为/users/{id}
)。
2. 统一接口(Uniform Interface)
通过 HTTP 协议的标准方法(GET、POST、PUT、DELETE 等)操作资源,实现接口的统一性和语义化:
HTTP 方法 | 语义 | 幂等性 | 示例 |
---|---|---|---|
GET | 获取资源 | 是 | GET /users (获取所有用户) |
POST | 创建资源 | 否 | POST /users (新建用户) |
PUT | 全量更新资源 | 是 | PUT /users/1 (更新 ID=1 的用户) |
PATCH | 部分更新资源 | 否 | PATCH /users/1 (更新用户部分字段) |
DELETE | 删除资源 | 是 | DELETE /users/1 (删除 ID=1 的用户) |
幂等性:多次执行同一操作,结果与执行一次相同(如 PUT、DELETE 是幂等的,POST 不是)。
3. 无状态(Stateless)
- 服务端不保存客户端状态:每次请求必须包含处理所需的所有信息(如认证 Token、参数),服务端不依赖之前的请求上下文。(易于扩展(服务端无需维护会话状态)、适合分布式系统)
4. 可缓存(Cacheable)
- 响应应明确声明是否可缓存(通过 HTTP 头如
Cache-Control
),利用客户端或代理服务器缓存资源,减少重复请求。
5. 分层系统(Layered System)
- 客户端无需直接连接服务端,可通过中间层(如负载均衡、API 网关)转发请求,提高系统的可扩展性和安全性。
6. 按需代码(Code-On-Demand,可选)
- 服务端可返回可执行代码(如 JavaScript)扩展客户端功能,但现代 API 设计中较少使用。
二、RESTful API 的设计示例
以“用户管理”为例,对比传统风格与 RESTful 风格的 API 设计:
操作 | 传统风格(非 RESTful) | RESTful 风格 |
---|---|---|
获取所有用户 | GET /getUserList |
GET /users |
获取指定用户 | GET /getUserById?id=1 |
GET /users/1 |
创建用户 | POST /createUser |
POST /users |
更新用户 | PUT /updateUser?id=1 |
PUT /users/1 |
删除用户 | DELETE /deleteUser?id=1 |
DELETE /users/1 |
关键区别:
- URI 是名词复数形式(如
/users
),表示资源集合。- HTTP 方法明确表达操作意图(如 GET 获取、POST 创建)。
- URI 中不包含动词,通过路径参数(如
/users/{id}
)定位具体资源。
三、RESTful 的常见实践
1. 状态码标准化
- 使用 HTTP 状态码表达操作结果,而非在响应体中自定义错误码:
200 OK
:请求成功(GET/PUT/PATCH)。201 Created
:资源创建成功(POST)。204 No Content
:删除成功(DELETE)。400 Bad Request
:客户端请求错误(如参数校验失败)。401 Unauthorized
:未认证。403 Forbidden
:无权限。404 Not Found
:资源不存在。500 Internal Server Error
:服务端内部错误。
2. 版本控制
- 在 URI 或 HTTP 头中标识 API 版本,便于兼容性管理:
- URI 路径版本控制:
/v1/users
。 - HTTP 头版本控制:
Accept: application/vnd.example.v1+json
。
- URI 路径版本控制:
3. 数据格式
- 请求和响应默认使用 JSON(轻量、易解析),也可支持 XML(通过
Accept
和Content-Type
头协商)。
4. HATEOAS(超媒体作为应用状态引擎)
- 高级 RESTful 实践,响应中包含相关资源的链接(如分页导航、操作入口),引导客户端发现可用功能。
- 示例(JSON 中包含链接):
{ "id": 1, "name": "Alice", "_links": { "self": { "href": "/users/1" }, "orders": { "href": "/users/1/orders" } } }
- 示例(JSON 中包含链接):
四、RESTful 与 RPC、GraphQL 的对比
特性 | RESTful | RPC(如 gRPC、Dubbo) | GraphQL |
---|---|---|---|
设计理念 | 资源为中心 | 动作为中心(调用远程方法) | 数据查询为中心 |
通信协议 | HTTP | 自定义协议(如 HTTP/2) | HTTP(通常用 POST) |
数据格式 | JSON/XML | 二进制(如 Protobuf) | JSON |
灵活性 | 较低(需预定义资源路径) | 高(灵活调用方法) | 极高(客户端指定返回字段) |
适用场景 | 公开 API、前后端分离 | 内部服务通信、高性能场景 | 复杂数据查询需求 |
RESTful 是一种以资源为中心、基于 HTTP 协议的 API 设计风格,强调 语义化、无状态、可缓存。它通过标准化的 HTTP 方法和 URI 设计,降低了前后端协作的复杂度,适合构建开放、可扩展的网络服务。在实际开发中,可结合具体需求灵活调整(如支持 HATEOAS 或部分妥协 REST 约束),也可与其他技术(如 GraphQL)互补使用。