505 lines
8.3 KiB
Markdown
505 lines
8.3 KiB
Markdown
|
|
# RESTful API 设计规范
|
|||
|
|
|
|||
|
|
::: info API 设计规范
|
|||
|
|
|
|||
|
|
本文档定义了 wwjcloud 框架的 RESTful API 设计规范,确保 API 的一致性、可读性和可维护性。
|
|||
|
|
|
|||
|
|
:::
|
|||
|
|
|
|||
|
|
## 基本原则
|
|||
|
|
|
|||
|
|
### 🎯 设计原则
|
|||
|
|
|
|||
|
|
- **资源导向**:API 应该围绕资源进行设计
|
|||
|
|
- **无状态**:每个请求都应该包含完整的信息
|
|||
|
|
- **统一接口**:使用标准的 HTTP 方法
|
|||
|
|
- **可缓存**:支持缓存机制
|
|||
|
|
- **分层系统**:支持分层架构
|
|||
|
|
|
|||
|
|
### 📝 命名规范
|
|||
|
|
|
|||
|
|
- **URL 使用小写字母**:`/api/member/list`
|
|||
|
|
- **单词间使用连字符**:`/api/user-profile`
|
|||
|
|
- **避免使用下划线**:不推荐 `/api/user_profile`
|
|||
|
|
- **使用复数形式**:`/api/members` 而不是 `/api/member`
|
|||
|
|
|
|||
|
|
## HTTP 方法
|
|||
|
|
|
|||
|
|
### 🔍 GET - 获取资源
|
|||
|
|
|
|||
|
|
**用途:** 获取资源列表或单个资源
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 获取资源列表
|
|||
|
|
GET /api/members
|
|||
|
|
|
|||
|
|
# 获取单个资源
|
|||
|
|
GET /api/members/123
|
|||
|
|
|
|||
|
|
# 获取资源的子资源
|
|||
|
|
GET /api/members/123/orders
|
|||
|
|
|
|||
|
|
# 查询参数
|
|||
|
|
GET /api/members?page=1&size=10&status=active
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应示例:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "获取成功",
|
|||
|
|
"data": {
|
|||
|
|
"list": [...],
|
|||
|
|
"total": 100,
|
|||
|
|
"page": 1,
|
|||
|
|
"size": 10
|
|||
|
|
},
|
|||
|
|
"timestamp": 1640995200
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ➕ POST - 创建资源
|
|||
|
|
|
|||
|
|
**用途:** 创建新资源
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 创建资源
|
|||
|
|
POST /api/members
|
|||
|
|
|
|||
|
|
# 请求体
|
|||
|
|
{
|
|||
|
|
"username": "john_doe",
|
|||
|
|
"email": "john@example.com",
|
|||
|
|
"status": 1
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应示例:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "创建成功",
|
|||
|
|
"data": {
|
|||
|
|
"id": 123,
|
|||
|
|
"username": "john_doe",
|
|||
|
|
"email": "john@example.com",
|
|||
|
|
"status": 1,
|
|||
|
|
"create_time": 1640995200
|
|||
|
|
},
|
|||
|
|
"timestamp": 1640995200
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ✏️ PUT - 更新资源
|
|||
|
|
|
|||
|
|
**用途:** 完整更新资源
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 更新资源
|
|||
|
|
PUT /api/members/123
|
|||
|
|
|
|||
|
|
# 请求体
|
|||
|
|
{
|
|||
|
|
"username": "john_doe_updated",
|
|||
|
|
"email": "john_updated@example.com",
|
|||
|
|
"status": 1
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应示例:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "更新成功",
|
|||
|
|
"data": {
|
|||
|
|
"id": 123,
|
|||
|
|
"username": "john_doe_updated",
|
|||
|
|
"email": "john_updated@example.com",
|
|||
|
|
"status": 1,
|
|||
|
|
"update_time": 1640995200
|
|||
|
|
},
|
|||
|
|
"timestamp": 1640995200
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 🔄 PATCH - 部分更新
|
|||
|
|
|
|||
|
|
**用途:** 部分更新资源
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 部分更新资源
|
|||
|
|
PATCH /api/members/123
|
|||
|
|
|
|||
|
|
# 请求体
|
|||
|
|
{
|
|||
|
|
"status": 0
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应示例:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "更新成功",
|
|||
|
|
"data": {
|
|||
|
|
"id": 123,
|
|||
|
|
"status": 0,
|
|||
|
|
"update_time": 1640995200
|
|||
|
|
},
|
|||
|
|
"timestamp": 1640995200
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 🗑️ DELETE - 删除资源
|
|||
|
|
|
|||
|
|
**用途:** 删除资源
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 删除资源
|
|||
|
|
DELETE /api/members/123
|
|||
|
|
|
|||
|
|
# 批量删除
|
|||
|
|
DELETE /api/members?ids=123,124,125
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**响应示例:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "删除成功",
|
|||
|
|
"data": null,
|
|||
|
|
"timestamp": 1640995200
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## URL 设计
|
|||
|
|
|
|||
|
|
### 📋 资源命名
|
|||
|
|
|
|||
|
|
**使用名词而非动词:**
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# ✅ 正确
|
|||
|
|
GET /api/members
|
|||
|
|
POST /api/members
|
|||
|
|
PUT /api/members/123
|
|||
|
|
DELETE /api/members/123
|
|||
|
|
|
|||
|
|
# ❌ 错误
|
|||
|
|
GET /api/getMembers
|
|||
|
|
POST /api/createMember
|
|||
|
|
PUT /api/updateMember
|
|||
|
|
DELETE /api/deleteMember
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 🔗 嵌套资源
|
|||
|
|
|
|||
|
|
**表示资源间的关系:**
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 获取用户的订单
|
|||
|
|
GET /api/members/123/orders
|
|||
|
|
|
|||
|
|
# 获取用户的特定订单
|
|||
|
|
GET /api/members/123/orders/456
|
|||
|
|
|
|||
|
|
# 为用户创建订单
|
|||
|
|
POST /api/members/123/orders
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 🔍 查询参数
|
|||
|
|
|
|||
|
|
**用于过滤、排序、分页:**
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 过滤
|
|||
|
|
GET /api/members?status=active&type=vip
|
|||
|
|
|
|||
|
|
# 排序
|
|||
|
|
GET /api/members?sort=create_time&order=desc
|
|||
|
|
|
|||
|
|
# 分页
|
|||
|
|
GET /api/members?page=1&size=10
|
|||
|
|
|
|||
|
|
# 搜索
|
|||
|
|
GET /api/members?keyword=john
|
|||
|
|
|
|||
|
|
# 组合使用
|
|||
|
|
GET /api/members?status=active&page=1&size=10&sort=create_time&order=desc
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 状态码规范
|
|||
|
|
|
|||
|
|
### ✅ 成功状态码
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
200 OK # 请求成功
|
|||
|
|
201 Created # 资源创建成功
|
|||
|
|
204 No Content # 请求成功,无返回内容
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### ❌ 客户端错误
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
400 Bad Request # 请求参数错误
|
|||
|
|
401 Unauthorized # 未授权访问
|
|||
|
|
403 Forbidden # 禁止访问
|
|||
|
|
404 Not Found # 资源不存在
|
|||
|
|
405 Method Not Allowed # 方法不允许
|
|||
|
|
409 Conflict # 资源冲突
|
|||
|
|
422 Unprocessable Entity # 请求格式正确但语义错误
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 🔧 服务器错误
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
500 Internal Server Error # 服务器内部错误
|
|||
|
|
502 Bad Gateway # 网关错误
|
|||
|
|
503 Service Unavailable # 服务不可用
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 请求头规范
|
|||
|
|
|
|||
|
|
### 📋 常用请求头
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 内容类型
|
|||
|
|
Content-Type: application/json
|
|||
|
|
|
|||
|
|
# 授权信息
|
|||
|
|
Authorization: Bearer <token>
|
|||
|
|
|
|||
|
|
# 接受的内容类型
|
|||
|
|
Accept: application/json
|
|||
|
|
|
|||
|
|
# 用户代理
|
|||
|
|
User-Agent: wwjcloud-client/1.0.0
|
|||
|
|
|
|||
|
|
# 语言设置
|
|||
|
|
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 🔐 认证头
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# JWT Token
|
|||
|
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
|||
|
|
|
|||
|
|
# API Key
|
|||
|
|
X-API-Key: your-api-key
|
|||
|
|
|
|||
|
|
# 自定义认证
|
|||
|
|
X-Auth-Token: your-auth-token
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 响应格式
|
|||
|
|
|
|||
|
|
### 📊 统一响应结构
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface ApiResponse<T = any> {
|
|||
|
|
code: number; // 状态码
|
|||
|
|
message: string; // 消息
|
|||
|
|
data: T; // 数据
|
|||
|
|
timestamp: number; // 时间戳
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 📝 响应示例
|
|||
|
|
|
|||
|
|
**成功响应:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "操作成功",
|
|||
|
|
"data": {
|
|||
|
|
"id": 123,
|
|||
|
|
"username": "john_doe",
|
|||
|
|
"email": "john@example.com"
|
|||
|
|
},
|
|||
|
|
"timestamp": 1640995200
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**错误响应:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 400,
|
|||
|
|
"message": "请求参数错误",
|
|||
|
|
"data": null,
|
|||
|
|
"timestamp": 1640995200
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**列表响应:**
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 200,
|
|||
|
|
"message": "获取成功",
|
|||
|
|
"data": {
|
|||
|
|
"list": [
|
|||
|
|
{
|
|||
|
|
"id": 123,
|
|||
|
|
"username": "john_doe",
|
|||
|
|
"email": "john@example.com"
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"total": 100,
|
|||
|
|
"page": 1,
|
|||
|
|
"size": 10
|
|||
|
|
},
|
|||
|
|
"timestamp": 1640995200
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 版本控制
|
|||
|
|
|
|||
|
|
### 🔢 版本策略
|
|||
|
|
|
|||
|
|
**URL 版本控制:**
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 版本 1
|
|||
|
|
GET /api/v1/members
|
|||
|
|
|
|||
|
|
# 版本 2
|
|||
|
|
GET /api/v2/members
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**请求头版本控制:**
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
GET /api/members
|
|||
|
|
Accept: application/vnd.wwjcloud.v1+json
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 📋 版本命名
|
|||
|
|
|
|||
|
|
- **主版本**:重大变更,不兼容
|
|||
|
|
- **次版本**:新功能,向后兼容
|
|||
|
|
- **修订版本**:Bug 修复,向后兼容
|
|||
|
|
|
|||
|
|
## 错误处理
|
|||
|
|
|
|||
|
|
### 🚨 错误响应格式
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"code": 400,
|
|||
|
|
"message": "请求参数错误",
|
|||
|
|
"data": {
|
|||
|
|
"errors": [
|
|||
|
|
{
|
|||
|
|
"field": "email",
|
|||
|
|
"message": "邮箱格式不正确"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"field": "username",
|
|||
|
|
"message": "用户名不能为空"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
"timestamp": 1640995200
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 📝 错误码规范
|
|||
|
|
|
|||
|
|
**业务错误码:**
|
|||
|
|
```typescript
|
|||
|
|
// 成功
|
|||
|
|
200: '操作成功'
|
|||
|
|
201: '创建成功'
|
|||
|
|
|
|||
|
|
// 客户端错误
|
|||
|
|
400: '请求参数错误'
|
|||
|
|
401: '未授权访问'
|
|||
|
|
403: '禁止访问'
|
|||
|
|
404: '资源不存在'
|
|||
|
|
409: '资源冲突'
|
|||
|
|
|
|||
|
|
// 服务器错误
|
|||
|
|
500: '服务器内部错误'
|
|||
|
|
502: '网关错误'
|
|||
|
|
503: '服务不可用'
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 最佳实践
|
|||
|
|
|
|||
|
|
### ✅ 推荐做法
|
|||
|
|
|
|||
|
|
1. **使用 HTTPS**:所有 API 都应该使用 HTTPS
|
|||
|
|
2. **参数验证**:严格验证所有输入参数
|
|||
|
|
3. **错误处理**:提供详细的错误信息
|
|||
|
|
4. **文档化**:提供完整的 API 文档
|
|||
|
|
5. **版本控制**:使用版本控制管理 API 变更
|
|||
|
|
6. **限流控制**:实现 API 限流机制
|
|||
|
|
7. **监控日志**:记录 API 调用日志
|
|||
|
|
|
|||
|
|
### ❌ 避免做法
|
|||
|
|
|
|||
|
|
1. **不要使用动词**:URL 应该使用名词
|
|||
|
|
2. **不要暴露内部错误**:不要返回敏感的错误信息
|
|||
|
|
3. **不要过度设计**:保持 API 简单易用
|
|||
|
|
4. **不要忽略缓存**:合理使用缓存机制
|
|||
|
|
5. **不要忽略安全**:实现适当的安全措施
|
|||
|
|
|
|||
|
|
## 示例
|
|||
|
|
|
|||
|
|
### 📋 完整的 API 示例
|
|||
|
|
|
|||
|
|
**会员管理 API:**
|
|||
|
|
|
|||
|
|
```http
|
|||
|
|
# 获取会员列表
|
|||
|
|
GET /api/v1/members?page=1&size=10&status=active
|
|||
|
|
|
|||
|
|
# 获取单个会员
|
|||
|
|
GET /api/v1/members/123
|
|||
|
|
|
|||
|
|
# 创建会员
|
|||
|
|
POST /api/v1/members
|
|||
|
|
Content-Type: application/json
|
|||
|
|
Authorization: Bearer <token>
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"username": "john_doe",
|
|||
|
|
"email": "john@example.com",
|
|||
|
|
"status": 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 更新会员
|
|||
|
|
PUT /api/v1/members/123
|
|||
|
|
Content-Type: application/json
|
|||
|
|
Authorization: Bearer <token>
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
"username": "john_doe_updated",
|
|||
|
|
"email": "john_updated@example.com",
|
|||
|
|
"status": 1
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 删除会员
|
|||
|
|
DELETE /api/v1/members/123
|
|||
|
|
Authorization: Bearer <token>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 下一步
|
|||
|
|
|
|||
|
|
::: tip 深入学习
|
|||
|
|
|
|||
|
|
1. **查看响应格式规范**:了解统一的响应格式
|
|||
|
|
2. **阅读错误码规范**:了解错误码定义
|
|||
|
|
3. **参考开发规范**:遵循开发规范
|
|||
|
|
4. **查看最佳实践**:学习最佳实践
|
|||
|
|
|
|||
|
|
:::
|
|||
|
|
|
|||
|
|
::: warning 注意事项
|
|||
|
|
|
|||
|
|
- 严格遵循 RESTful 设计原则
|
|||
|
|
- 保持 API 的一致性和可读性
|
|||
|
|
- 提供完整的错误处理
|
|||
|
|
- 实现适当的安全措施
|
|||
|
|
|
|||
|
|
:::
|