Skip to content

RESTful API 设计

欢迎来到 RESTful API 设计知识库!

🌐 RESTful API 简介

REST (Representational State Transfer) 是一种软件架构风格,用于设计网络应用程序的API。RESTful API 通过 HTTP 协议进行通信,使用标准的 HTTP 方法操作资源。

🎯 REST 核心原则

1. 资源(Resources)

一切皆资源,每个资源都有唯一的 URI。

/users          # 用户集合
/users/123      # 单个用户
/users/123/posts # 用户的文章

2. 表现层(Representation)

资源的表现形式,通常使用 JSON。

json
{
  "id": 123,
  "username": "张三",
  "email": "zhang@example.com"
}

3. 状态转移(State Transfer)

通过 HTTP 方法操作资源状态。

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

4. 统一接口

使用标准的 HTTP 方法和状态码。

5. 无状态

每个请求都包含完整信息,服务器不保存客户端状态。

6. 可缓存

响应可以标记为可缓存或不可缓存。

📖 HTTP 方法

方法操作幂等性安全性示例
GET查询GET /users
POST创建POST /users
PUT更新(完整)PUT /users/123
PATCH更新(部分)PATCH /users/123
DELETE删除DELETE /users/123

🎯 URL 设计规范

✅ 好的设计

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

GET    /users/123/posts    # 获取用户的文章
POST   /users/123/posts    # 创建用户的文章

❌ 不好的设计

GET  /getUser?id=123       # 动词在 URL 中
POST /createUser           # 动词在 URL 中
GET  /users/delete/123     # 使用错误的 HTTP 方法
GET  /user/123             # 单数形式(应该使用复数)

设计原则

  1. 使用名词而非动词

    • ✅ GET /users
    • ❌ GET /getUsers
  2. 使用复数形式

    • ✅ /users、/posts
    • ❌ /user、/post
  3. 使用连字符分隔

    • ✅ /user-posts
    • ❌ /user_posts、/userPosts
  4. 小写字母

    • ✅ /users/123/posts
    • ❌ /Users/123/Posts
  5. 避免深层嵌套

    • ✅ /users/123/posts
    • ❌ /users/123/posts/456/comments/789

📊 HTTP 状态码

2xx 成功

  • 200 OK - 请求成功
  • 201 Created - 创建成功
  • 204 No Content - 删除成功,无内容返回

4xx 客户端错误

  • 400 Bad Request - 请求参数错误
  • 401 Unauthorized - 未认证
  • 403 Forbidden - 无权限
  • 404 Not Found - 资源不存在
  • 409 Conflict - 资源冲突(如重复创建)
  • 422 Unprocessable Entity - 参数验证失败
  • 429 Too Many Requests - 请求过多,限流

5xx 服务器错误

  • 500 Internal Server Error - 服务器内部错误
  • 502 Bad Gateway - 网关错误
  • 503 Service Unavailable - 服务不可用

📝 请求与响应设计

请求示例

http
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Authorization: Bearer <token>

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

响应示例

http
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/users/123

{
  "code": 0,
  "message": "创建成功",
  "data": {
    "id": 123,
    "username": "zhangsan",
    "email": "zhang@example.com",
    "age": 25,
    "createdAt": "2024-01-01T12:00:00Z"
  }
}

统一响应格式

json
{
  "code": 0,              // 业务状态码,0 表示成功
  "message": "success",   // 提示信息
  "data": {},             // 业务数据
  "timestamp": 1234567890 // 时间戳
}

错误响应

json
{
  "code": 400,
  "message": "参数验证失败",
  "errors": [
    {
      "field": "email",
      "message": "邮箱格式不正确"
    }
  ],
  "timestamp": 1234567890
}

🔍 查询参数

分页

GET /users?page=1&pageSize=20
GET /users?offset=0&limit=20

响应:

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

排序

GET /users?sort=age:desc
GET /users?sort=-age          # - 表示降序
GET /users?sort=age,-createdAt  # 多字段排序

过滤

GET /users?status=active
GET /users?age[gte]=18&age[lte]=30
GET /users?city=北京&status=active

字段选择

GET /users?fields=id,username,email

搜索

GET /users?q=张三
GET /articles?keyword=Redis

🔐 认证与授权

1. API Key

http
GET /api/users
X-API-Key: your_api_key

2. Bearer Token (JWT)

http
GET /api/users
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

3. OAuth 2.0

http
GET /api/users
Authorization: Bearer <access_token>

📌 版本控制

1. URL 版本

https://api.example.com/v1/users
https://api.example.com/v2/users

2. Header 版本

http
GET /users
Accept: application/vnd.example.v1+json

3. 参数版本

GET /users?version=1

推荐: URL 版本,简单直观。

🚀 最佳实践示例

CRUD 完整示例

javascript
// 用户 API

// 1. 获取用户列表
GET /api/v1/users?page=1&pageSize=20&sort=-createdAt

Response 200:
{
  "code": 0,
  "data": {
    "list": [
      {
        "id": 1,
        "username": "zhangsan",
        "email": "zhang@example.com",
        "createdAt": "2024-01-01T12:00:00Z"
      }
    ],
    "pagination": {
      "page": 1,
      "pageSize": 20,
      "total": 100
    }
  }
}

// 2. 获取单个用户
GET /api/v1/users/123

Response 200:
{
  "code": 0,
  "data": {
    "id": 123,
    "username": "zhangsan",
    "email": "zhang@example.com",
    "profile": {
      "age": 25,
      "city": "北京"
    },
    "createdAt": "2024-01-01T12:00:00Z"
  }
}

// 3. 创建用户
POST /api/v1/users
Content-Type: application/json

{
  "username": "lisi",
  "email": "li@example.com",
  "password": "123456"
}

Response 201:
{
  "code": 0,
  "message": "创建成功",
  "data": {
    "id": 124,
    "username": "lisi",
    "email": "li@example.com",
    "createdAt": "2024-01-01T12:00:00Z"
  }
}

// 4. 更新用户(完整)
PUT /api/v1/users/123

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

Response 200:
{
  "code": 0,
  "message": "更新成功",
  "data": {
    "id": 123,
    "username": "zhangsan",
    "email": "newzhang@example.com",
    "age": 26,
    "updatedAt": "2024-01-01T12:00:00Z"
  }
}

// 5. 更新用户(部分)
PATCH /api/v1/users/123

{
  "email": "newzhang@example.com"
}

Response 200:
{
  "code": 0,
  "message": "更新成功",
  "data": {
    "id": 123,
    "email": "newzhang@example.com"
  }
}

// 6. 删除用户
DELETE /api/v1/users/123

Response 204: (无内容)

💡 设计建议

1. 使用 HTTPS

所有 API 都应该使用 HTTPS 加密传输。

2. 合理使用 HTTP 方法

  • GET - 查询,不修改数据
  • POST - 创建资源
  • PUT - 完整更新
  • PATCH - 部分更新
  • DELETE - 删除

3. 提供清晰的错误信息

json
{
  "code": 400,
  "message": "参数验证失败",
  "errors": [
    {
      "field": "email",
      "message": "邮箱已存在"
    }
  ]
}

4. 支持 CORS

http
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization

5. 限流

http
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1234567890

6. 文档化

使用 Swagger/OpenAPI 自动生成文档。

7. 幂等性设计

PUT、DELETE 应该是幂等的,多次调用结果相同。

8. 异步任务

POST /api/tasks

Response 202 Accepted:
{
  "taskId": "abc123",
  "status": "processing",
  "statusUrl": "/api/tasks/abc123"
}

GET /api/tasks/abc123

Response 200:
{
  "taskId": "abc123",
  "status": "completed",
  "result": {...}
}

📖 学习资源

推荐阅读

工具推荐

  • Postman - API 测试工具
  • Swagger - API 文档工具
  • Insomnia - API 客户端

准备好了吗?开始设计你的 RESTful API!