RESTful API
架构指南

构建可扩展、高性能、松耦合的现代网络服务

什么是 RESTful?

REST (Representational State Transfer,表现层状态转移) 是一种软件架构风格,由 Roy Fielding 在 2000 年的博士论文中提出。它不是标准,而是一组约束条件和原则。符合 REST 架构风格的 Web API 被称为 RESTful API

核心思想

REST 的核心思想是将网络上的所有事物抽象为资源 (Resource),并通过统一的接口(HTTP 方法)对资源进行操作,实现状态的转移。每个资源都有唯一的标识符(URI),客户端通过操作资源的表述(Representation)来修改服务端状态。

Richardson 成熟度模型

  • Level 0: 使用 HTTP 作为传输协议
  • Level 1: 引入资源概念,每个资源有独立的 URI
  • Level 2: 正确使用 HTTP 方法(GET/POST/PUT/DELETE)
  • Level 3: HATEOAS,完全的超媒体驱动

六大架构约束

REST 架构通过六个核心约束来定义系统的行为。这些约束共同作用,赋予了 RESTful 系统高可扩展性、独立性和性能。

1. 客户-服务器 (Client-Server)

关注点分离。服务端专注数据存储和业务逻辑,客户端专注用户界面和交互。两者通过接口通信,可独立演化。

2. 无状态 (Stateless)

服务器不保存客户端的会话状态。每个请求必须包含处理该请求所需的所有信息。这提高了可见性、可靠性和可扩展性。

# 无状态请求示例:每次请求携带完整认证信息
GET /api/users/123
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Content-Type: application/json

3. 缓存 (Cacheable)

响应数据必须显式声明是否可缓存。合理的缓存机制可以减少客户端与服务器的交互,降低延迟。

4. 统一接口 (Uniform Interface)

这是 REST 的核心。包括资源的识别、通过表述操作资源、自描述消息和 HATEOAS。它简化了系统架构,使不同部分可以独立优化。

统一接口的四个约束:

  • 资源标识:通过 URI 唯一标识资源
  • 资源操作:通过表述(JSON/XML)操作资源
  • 自描述消息:请求/响应包含处理所需的所有信息
  • HATEOAS:通过超链接导航应用状态

5. 分层系统 (Layered System)

客户端不需要知道它是直接连接到最终服务器,还是连接到中间的代理或负载均衡器。这增强了系统的安全性。

6. 按需代码 (Code on Demand) - 可选

服务器可以通过传输可执行代码(如 JavaScript)来扩展客户端的功能。

REST Client-Server Stateless Cacheable Uniform Interface Layered System Code on Demand [图1] REST 架构约束关系图

资源与 URI 设计

在 REST 中,资源 (Resource) 是核心。URI (统一资源标识符) 用于唯一标识资源。

设计原则

  • 使用名词,避免动词:URI 应代表“事物”,操作由 HTTP 方法指定。
  • 使用复数:例如 /users 而不是 /user,表示资源集合。
  • 层级结构:使用斜杠 / 表示层级关系,如 /users/1/orders
  • 连字符:使用 - 提高可读性,避免使用下划线 _
  • 小写字母:URI 路径应尽量使用小写。

HTTP 方法与状态码映射

对资源的操作通过标准的 HTTP 方法实现。以下是以“用户 (User)”资源为例的标准端点设计。

HTTP Method URI Endpoint Action & Status GET /users List Users 200 OK POST /users Create User 201 Created GET /users/{id} Get User Detail 200 OK / 404 Not Found PUT /users/{id} Replace User 200 OK / 204 No Content DELETE /users/{id} Delete User 204 No Content [图2] 资源操作映射表

请求与响应 (JSON)

RESTful API 通常使用 JSON (JavaScript Object Notation) 作为数据交换格式。它轻量、易读且易于解析。

请求/响应交互流程

以下展示了一个创建新用户的完整交互时序。

Client Server POST /users { "name": "Neo", "role": "The One" } Processing 201 Created { "id": 101, "name": "Neo", "link": "/users/101" } [图3] 创建资源交互时序图

HTTP 状态码

准确使用状态码是 RESTful API 的关键。它们向客户端传达请求的处理结果。

2xx 成功 200 OK 201 Created 204 No Content 3xx 重定向 301 Moved Perm. 304 Not Modified 4xx 客户端错误 400 Bad Request 401 Unauthorized 403 Forbidden 404 Not Found 5xx 服务端错误 500 Internal Error 503 Unavailable 1xx 信息 STATUS [图4] 状态码分类轮状图

HATEOAS

HATEOAS (Hypermedia as the Engine of Application State) 是 REST 的最高成熟度级别。它要求 API 在响应中包含链接,指导客户端进行下一步操作。

客户端不需要硬编码 URL,而是通过跟随链接来发现资源。

示例响应

{
  "id": 1,
  "name": "Alice",
  "balance": 1000,
  "_links": {
    "self": { "href": "/accounts/1" },
    "deposit": { "href": "/accounts/1/deposit" },
    "withdraw": { "href": "/accounts/1/withdraw" },
    "transfer": { "href": "/accounts/1/transfer" }
  }
}
Account Resource Deposit Withdraw Transfer History [图5] HATEOAS 资源导航图

API 版本化

随着业务发展,API 必然会发生变化。版本化策略能保证旧客户端的兼容性。

  • URI 版本化 (最常用): GET /v1/users
  • 请求头版本化: Accept: application/vnd.myapi.v1+json
  • 查询参数版本化: GET /users?version=1

建议使用 URI 版本化,因为它最直观、易于理解和测试。

安全与认证

RESTful API 的安全性是生产环境中的核心考量。常见的认证方式包括:

JWT (JSON Web Token)

无状态认证的首选方案,适合分布式系统。

# 请求头携带 JWT Token
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

# Token 结构: Header.Payload.Signature
# Header:  {"alg": "HS256", "typ": "JWT"}
# Payload: {"sub": "1234", "name": "John", "exp": 1516239022}

OAuth 2.0

授权框架,适用于第三方应用访问。支持多种授权流程:

  • Authorization Code: Web 应用最安全的方式
  • Client Credentials: 服务间通信
  • PKCE: 移动/SPA 应用推荐

安全最佳实践

  • HTTPS: 始终使用 TLS 加密传输
  • 速率限制: 防止恶意请求和 DDoS 攻击
  • 输入验证: 防止注入攻击
  • CORS 配置: 限制跨域访问

最佳实践

遵循这些最佳实践可以设计出更稳定、易用的 API。

分页与过滤

# 分页
GET /api/users?page=2&limit=20

# 过滤
GET /api/users?status=active&role=admin

# 排序
GET /api/users?sort=created_at&order=desc

# 字段选择
GET /api/users?fields=id,name,email

错误处理

统一的错误响应格式有助于客户端处理异常。

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "请求参数验证失败",
    "details": [
      {"field": "email", "message": "邮箱格式不正确"},
      {"field": "age", "message": "必须大于0"}
    ],
    "timestamp": "2026-01-16T10:30:00Z",
    "request_id": "req_abc123"
  }
}

文档与测试

  • OpenAPI/Swagger: 使用标准规范描述 API
  • 示例请求: 提供cURL/HTTPie 示例
  • 在线测试: 集成 Playground 或 Postman Collection
  • 变更日志: 记录 API 版本变更历史

常见问题 (FAQ)

Q: PUT 和 PATCH 的区别是什么? +

PUT 用于完整替换资源,需要提供资源的所有字段;PATCH 用于部分更新,只提供需要修改的字段。PATCH 更节省带宽,但 PUT 具有幂等性保证。

Q: 为什么要用名词而不是动词设计 URI? +

REST 将 HTTP 方法作为动词(操作),URI 作为名词(资源)。这样设计使接口更统一、更可预测。例如 DELETE /users/1POST /deleteUser 更符合 REST 风格。

Q: 如何处理 API 的嵌套资源? +

嵌套资源可以通过层级 URI 表示,如 /users/1/orders。但嵌套不应超过3层,否则建议使用查询参数或独立端点如 /orders?user_id=1

Q: 无状态是否意味着不能使用认证? +

不是。无状态指服务器不保存会话状态,每次请求需自带认证信息。JWT 就是典型的无状态认证方案,Token 包含所有验证所需信息,服务器无需存储会话。