name: api-design-patterns description: 使用RESTful模式、GraphQL模式、版本控制策略和错误处理约定设计健壮的API。支持OpenAPI/Swagger文档和SDK生成模式。触发于API设计、模式定义、端点架构或开发者体验请求。 license: MIT complexity: intermediate time_to_learn: 30min tags:
- api
- rest
- graphql
- openapi
- design-patterns inputs:
- service-requirements
- data-models outputs:
- api-specification
- endpoint-design
- openapi-document side_effects:
- creates-files triggers:
- user-asks-about-api
- user-asks-about-rest
- user-asks-about-graphql
- file-type:*.openapi.yaml
- project-has-openapi-spec complements:
- backend-implementation-patterns
- mcp-builder tier: core
API设计模式
构建开发者喜欢使用的API。
设计原则
API设计三定律
- 可预测性:整个过程中保持一致的模式
- 可发现性:自我文档化,直观的命名
- 可演化性:可以在不破坏客户端的情况下改变
API优先思维
设计 → 文档 → 模拟 → 构建 → 测试 → 部署
不是:构建 → 文档(也许) → 希望它能工作
REST模式
资源命名
# 集合
GET /users # 列出用户
POST /users # 创建用户
# 项目
GET /users/{id} # 获取用户
PUT /users/{id} # 替换用户
PATCH /users/{id} # 更新用户
DELETE /users/{id} # 删除用户
# 嵌套资源
GET /users/{id}/posts # 用户的帖子
POST /users/{id}/posts # 为用户创建帖子
# 操作(当CRUD不合适时)
POST /users/{id}/activate
POST /orders/{id}/cancel
命名约定
| 做 | 不要 |
|---|---|
/users |
/getUsers, /user-list |
/users/{id} |
/users/get/{id} |
/users/{id}/posts |
/getUserPosts |
| 复数名词 | URL中的动词 |
| 小写,连字符 | 驼峰式,下划线 |
HTTP方法
| 方法 | 目的 | 幂等性 | 安全性 |
|---|---|---|---|
| GET | 读取 | 是 | 是 |
| POST | 创建 | 否 | 否 |
| PUT | 替换 | 是 | 否 |
| PATCH | 更新 | 否* | 否 |
| DELETE | 删除 | 是 | 否 |
*如果设计得当,PATCH可以是幂等的
状态码
| 代码 | 含义 | 使用时机 |
|---|---|---|
| 200 | OK | 成功的GET、PUT、PATCH |
| 201 | Created | 成功的POST并创建新资源 |
| 204 | No Content | 成功的DELETE |
| 400 | Bad Request | 无效输入 |
| 401 | Unauthorized | 缺少/无效认证 |
| 403 | Forbidden | 有效认证,但无权限 |
| 404 | Not Found | 资源不存在 |
| 409 | Conflict | 重复、状态冲突 |
| 422 | Unprocessable | 有效语法,无效语义 |
| 429 | Too Many Requests | 被限速 |
| 500 | Server Error | 未处理的服务器错误 |
请求/响应模式
请求体
{
"email": "user@example.com",
"name": "John Doe",
"preferences": {
"newsletter": true
}
}
响应:单资源
{
"data": {
"id": "usr_123",
"type": "user",
"attributes": {
"email": "user@example.com",
"name": "John Doe",
"createdAt": "2024-01-15T10:30:00Z"
},
"relationships": {
"organization": {
"id": "org_456",
"type": "organization"
}
}
}
}
响应:集合
{
"data": [
{ "id": "usr_123", "type": "user", ... },
{ "id": "usr_124", "type": "user", ... }
],
"meta": {
"total": 150,
"page": 1,
"perPage": 20
},
"links": {
"self": "/users?page=1",
"next": "/users?page=2",
"last": "/users?page=8"
}
}
错误响应
{
"error": {
"code": "VALIDATION_ERROR",
"message": "无效请求参数",
"details": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "必须是有效的电子邮件地址"
}
],
"requestId": "req_abc123"
}
}
分页模式
基于偏移
GET /users?page=2&perPage=20
GET /users?offset=20&limit=20
优点:简单,熟悉 缺点:与实时数据不一致,大型数据集上慢
基于游标
GET /users?cursor=eyJpZCI6MTIzfQ&limit=20
响应:
{
"data": [...],
"cursors": {
"before": "eyJpZCI6MTAzfQ",
"after": "eyJpZCI6MTIzfQ"
},
"hasMore": true
}
优点:一致,性能好 缺点:不能跳转到第N页
基于键集
GET /users?after_id=123&limit=20
优点:性能非常好 缺点:需要可排序的唯一字段
过滤、排序、搜索
过滤
# 简单
GET /users?status=active
# 多个值
GET /users?status=active,pending
# 操作符
GET /users?created_at[gte]=2024-01-01
GET /users?name[contains]=john
# 嵌套
GET /users?organization.name=Acme
排序
# 单字段
GET /users?sort=createdAt
# 降序
GET /users?sort=-createdAt
# 多字段
GET /users?sort=-createdAt,name
字段选择
GET /users?fields=id,name,email
GET /users?fields[user]=id,name&fields[posts]=title
搜索
GET /users?q=john
GET /users?search=john+doe
版本控制策略
URL路径(推荐用于主要版本)
GET /v1/users
GET /v2/users
优点:明确,可缓存 缺点:URL污染
头部
GET /users
Accept: application/vnd.api+json; version=2
优点:URL干净 缺点:难以测试,不够可见
查询参数
GET /users?version=2
优点:易于测试 缺点:破坏缓存,URL污染
弃用模式
Deprecation: true
Sunset: Sat, 31 Dec 2024 23:59:59 GMT
Link: </v2/users>; rel="successor-version"
认证模式
API密钥
# 头部
Authorization: Api-Key sk_live_abc123
# 查询(避免 - 记录在URL中)
GET /users?api_key=sk_live_abc123 <!-- allow-secret -->
Bearer令牌(OAuth2/JWT)
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
签名请求(AWS风格)
Authorization: HMAC-SHA256 Credential=key/date/region/service,
SignedHeaders=host;x-date,
Signature=abc123
速率限制
头部
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640000000
Retry-After: 60
响应(429)
{
"error": {
"code": "RATE_LIMITED",
"message": "超过速率限制",
"retryAfter": 60
}
}
策略
| 策略 | 描述 | 使用案例 |
|---|---|---|
| 固定窗口 | 每分钟X请求 | 简单限制 |
| 滑动窗口 | 滚动时间窗口 | 平滑限制 |
| 令牌桶 | 突发允许 | 流量峰值 |
| 漏桶 | 恒定速率 | 稳定吞吐量 |
GraphQL模式
模式设计
type User {
id: ID!
email: String!
name: String
posts(first: Int, after: String): PostConnection!
createdAt: DateTime!
}
type Post {
id: ID!
title: String!
content: String!
author: User!
}
type PostConnection {
edges: [PostEdge!]!
pageInfo: PageInfo!
}
type Query {
user(id: ID!): User
users(filter: UserFilter, first: Int, after: String): UserConnection!
}
type Mutation {
createUser(input: CreateUserInput!): CreateUserPayload!
updateUser(id: ID!, input: UpdateUserInput!): UpdateUserPayload!
}
命名约定
| 元素 | 约定 | 示例 |
|---|---|---|
| 类型 | PascalCase | User, BlogPost |
| 字段 | camelCase | firstName, createdAt |
| 参数 | camelCase | userId, first |
| 枚举 | SCREAMING_SNAKE | USER_STATUS, ACTIVE |
| 突变 | verbNoun | createUser, updatePost |
错误处理
{
"data": null,
"errors": [
{
"message": "用户未找到",
"locations": [{ "line": 2, "column": 3 }],
"path": ["user"],
"extensions": {
"code": "NOT_FOUND",
"timestamp": "2024-01-15T10:30:00Z"
}
}
]
}
OpenAPI文档
基本结构
openapi: 3.0.3
info:
title: 我的API
version: 1.0.0
description: API描述
servers:
- url: https://api.example.com/v1
description: 生产环境
paths:
/users:
get:
summary: 列出用户
operationId: listUsers
tags: [Users]
parameters:
- name: page
in: query
schema:
type: integer
default: 1
responses:
'200':
description: 成功响应
content:
application/json:
schema:
$ref: '#/components/schemas/UserList'
components:
schemas:
User:
type: object
required: [id, email]
properties:
id:
type: string
format: uuid
email:
type: string
format: email
相关技能
互补技能(一起使用)
- backend-implementation-patterns - 实现您设计的API
- testing-patterns - 测试您的API端点
- deployment-cicd - 部署和版本化您的API
替代技能(类似目的)
- mcp-builder - 如果构建MCP服务器而不是REST/GraphQL API
先决技能(先学习)
- 无要求 - 这是基础设计技能
参考
references/openapi-template.md- 完整的OpenAPI模板references/error-codes.md- 标准错误代码目录references/sdk-patterns.md- 客户端SDK设计模式