RESTful API 设计完整指南:原则、规范与最佳实践

分类:Web 协议 | 阅读时间:约18分钟 | 最后更新:2026-04-10

核心要点

目录

flowchart LR
        P1["客户端-服务器"]
        P2["无状态"]
        P3["可缓存"]
        P4["分层系统"]
        P5["统一接口"]
        P6["按需代码"]
flowchart LR
    Do["✅ 应该"]
    Dont["❌ 避免"]
    Do --> D1["使用名词 /users"]
    Do --> D2["使用复数"]
    Do --> D3["嵌套资源"]
    Dont --> X1["使用动词 /getUsers"]
    Dont --> X2["文件扩展名 .json"]
sequenceDiagram
    participant C as 客户端
    participant S as REST API
    C->>S: POST /users {name:张三}
    S->>C: 201 Created {id:456}
    C->>S: GET /users/456
    S->>C: 200 OK {id:456}

什么是REST和RESTful API?

REST(Representational State Transfer,表述性状态转移)是一种软件架构风格,由Roy Fielding在2000年的博士论文中首次提出。RESTful API则是遵循REST原则设计的Web API接口。

RESTful API的核心特征包括:

REST核心原则

原则 说明 实现方式
客户端-服务器分离 客户端与服务端独立演化,互不依赖 前后端分离架构
无状态 每个请求包含所有必要信息,服务端不保存会话状态 请求中携带认证信息
可缓存 响应必须定义是否可缓存,减少网络往返 Cache-Control header
统一接口 资源通过统一接口访问,操作语义标准化 HTTP方法+URL定位资源
分层系统 客户端无法判断是否直连终端服务器 通过网关、负载均衡器分层

URL设计规范

资源命名基本原则

正确做法:使用名词表示资源

GET    /users          # 获取用户列表
GET    /users/123      # 获取ID为123的用户
POST   /users          # 创建新用户
PUT    /users/123      # 更新用户
DELETE /users/123      # 删除用户

错误做法:URL中包含动词

GET    /getUsers       # 错误:使用动词
POST   /createUser     # 错误:使用动词
DELETE /deleteUser/123 # 错误:使用动词

嵌套资源表示层级关系

# 用户123发表的所有文章
GET /users/123/articles

# 用户123的文章456的评论
GET /users/123/articles/456/comments

# 推荐:嵌套不超过2-3层
GET /users/123/posts
GET /posts/456/comments

注意:嵌套层级控制

嵌套层级不宜超过3层,过深的嵌套会使URL复杂且难以维护。如果层级过深,考虑使用查询参数或直接使用根资源。

命名规范

规范 推荐 不推荐
复数名词 /users /user
小写字母 /user-profiles /UserProfiles
kebab-case /order-items /order_items
清晰简洁 /articles/123 /articles/show/123

HTTP方法使用

RESTful API使用HTTP方法表达操作语义:

方法 用途 幂等性 安全性 请求体
GET 获取资源 是 是 无
POST 创建资源 否 否 有
PUT 全量更新 是 否 有
PATCH 部分更新 否 否 有
DELETE 删除资源 是 否 通常无

GET - 获取资源

GET /users/123
GET /users/123?fields=name,email HTTP/1.1
Host: api.example.com
Accept: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
响应示例
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=3600

{
  "id": 123,
  "name": "张三",
  "email": "zhangsan@example.com",
  "created_at": "2026-01-15T10:30:00Z"
}

POST - 创建资源

POST /users
POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

{
  "name": "李四",
  "email": "lisi@example.com",
  "password": "secure_password_123"
}
成功响应 - 201 Created
HTTP/1.1 201 Created
Location: /users/456
Content-Type: application/json

{
  "id": 456,
  "name": "李四",
  "email": "lisi@example.com",
  "created_at": "2026-04-10T08:00:00Z"
}

PUT vs PATCH - 全量更新与部分更新

PUT - 全量更新(需要提供完整资源)
PUT /users/123 HTTP/1.1
Content-Type: application/json

{
  "id": 123,
  "name": "张三更新版",
  "email": "zhangsan_new@example.com",
  "role": "admin",
  "status": "active"
}
-- 注意:PUT需要包含所有字段,缺失字段会被置为null或默认值 --
PATCH - 部分更新(只需提供要修改的字段)
PATCH /users/123 HTTP/1.1
Content-Type: application/json

{
  "name": "张三更新版"
}
-- 注意:PATCH只需包含要修改的字段,其他字段保持不变 --

HTTP状态码

合理使用HTTP状态码是RESTful API的重要实践:

状态码 含义 使用场景
2xx 成功
200 OK 请求成功 GET成功、PUT/PATCH更新成功
201 Created 资源创建成功 POST创建新资源,响应中包含Location头
204 No Content 无返回内容 DELETE成功,响应无body
3xx 重定向
304 Not Modified 资源未修改 配合ETag实现缓存
4xx 客户端错误
400 Bad Request 请求格式错误 参数校验失败、JSON格式错误
401 Unauthorized 未认证 缺少或无效的认证信息
403 Forbidden 无权限 认证通过但无访问权限
404 Not Found 资源不存在 URL对应的资源不存在
409 Conflict 资源冲突 重复创建、版本冲突
422 Unprocessable Entity 语义错误 请求格式正确但语义错误
429 Too Many Requests 请求过多 触发限流
5xx 服务端错误
500 Internal Server Error 服务端错误 通用服务端异常
502 Bad Gateway 网关错误 上游服务异常
503 Service Unavailable 服务不可用 维护或过载

查看完整的状态码说明:HTTP状态码速查工具

请求与响应设计

统一响应格式

成功响应
{
  "data": {
    "id": 123,
    "name": "张三",
    "email": "zhangsan@example.com"
  },
  "meta": {
    "request_id": "req_abc123",
    "timestamp": "2026-04-10T08:00:00Z"
  }
}
分页响应
{
  "data": [...],
  "pagination": {
    "page": 2,
    "per_page": 20,
    "total": 100,
    "total_pages": 5
  },
  "links": {
    "self": "/users?page=2",
    "next": "/users?page=3",
    "prev": "/users?page=1"
  }
}

请求头设计

请求头 说明 示例
Accept 告诉服务器客户端能处理的格式 application/json
Content-Type 请求体的格式 application/json
Authorization 认证信息 Bearer xxx
If-None-Match 条件请求,用于缓存 "123456"
Idempotency-Key 幂等性键,防止重复提交 uuid-xxx

错误处理

统一的错误响应格式对客户端调试至关重要:

错误响应格式
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "请求参数校验失败",
    "details": [
      {
        "field": "email",
        "message": "邮箱格式不正确"
      },
      {
        "field": "password",
        "message": "密码长度至少8位"
      }
    ],
    "request_id": "req_abc123"
  }
}

常见错误码设计模式

错误码命名规范

// 使用大写下划线格式
VALIDATION_ERROR      // 校验错误
RESOURCE_NOT_FOUND    // 资源不存在
UNAUTHORIZED         // 未认证
FORBIDDEN            // 无权限
RATE_LIMITED         // 限流
INTERNAL_ERROR       // 服务端错误

错误响应示例

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "创建用户失败",
    "details": [
      {"field": "email", "message": "邮箱已被注册"},
      {"field": "username", "message": "用户名不能为空"}
    ],
    "request_id": "req_xyz789"
  }
}

API版本管理

API版本管理确保前端与后端可以独立演进。常见的版本管理策略:

策略 示例 优点 缺点
URL路径 /api/v1/users 直观、强制版本感知 URL变更
Header API-Version: v1 URL不变 不够直观
查询参数 /api/users?version=1 简单 可能被缓存
URL路径版本管理示例
# v1版本
GET /api/v1/users/123

# v2版本 - 可能返回不同结构
GET /api/v2/users/123

# v2响应可能包含v1没有的字段
{
  "id": 123,
  "name": "张三",
  "email": "zhangsan@example.com",
  "avatar_url": "https://...",
  "created_at": "2026-01-15T10:30:00Z",
  "updated_at": "2026-04-10T08:00:00Z"
}

版本兼容策略

认证与安全

常见认证方式

方式 适用场景 安全性
API Key 服务端间调用 中等
Basic Auth 简单场景,不推荐 低
Bearer Token (JWT) Web/Mobile应用 高
OAuth 2.0 第三方授权 高
JWT认证示例
# 请求头携带Token
GET /api/v1/users/123 HTTP/1.1
Host: api.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

# Token Payload示例
{
  "sub": "user_123",
  "name": "张三",
  "role": "admin",
  "exp": 1712720000
}

安全最佳实践

CORS跨域配置

如果API有跨域需求,正确配置CORS头:

Access-Control-Allow-Origin: https://your-frontend.com
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400

最佳实践总结

RESTful API设计 Checklist