API设计框架Skill api-design-framework

提供REST、GraphQL、gRPC API设计的综合指导,确保API的一致性、可用性和可维护性,适用于设计新API、建立API规范、创建API文档等场景。

后端开发 0 次安装 0 次浏览 更新于 3/2/2026

API设计框架

概览

这项技能提供了全面的设计指导,用于设计健壮、可扩展且对开发者友好的API。无论是构建REST、GraphQL还是gRPC服务,此框架确保了一致性、可用性和可维护性。

何时使用这项技能:

  • 设计新的API端点或服务
  • 为团队或组织建立API约定
  • 审核API设计以确保一致性和最佳实践
  • 迁移或版本控制现有API
  • 创建API文档(OpenAPI、AsyncAPI)
  • 在REST、GraphQL或gRPC之间做出选择

API设计原则

1. 开发者体验优先

API应直观且自文档化:

  • 清晰、一致的命名约定
  • 可预测的行为和响应
  • 全面的文档
  • 有帮助的错误消息

2. 一致性优于巧妙

遵循既定模式而不是发明新模式:

  • 标准的HTTP方法和状态代码(REST)
  • 常规查询结构(GraphQL)
  • 惯用的proto定义(gRPC)

3. 进化而不破坏变更

从第一天起就为变更设计:

  • API版本控制策略
  • 向后兼容性考虑
  • 弃用政策
  • 迁移路径

4. 性能由设计决定

考虑性能影响:

  • 大数据集的分页
  • 过滤和部分响应
  • 缓存策略
  • 速率限制

REST API设计

资源命名约定

对资源使用复数名词:

✅ GET /users
✅ GET /users/123
✅ GET /users/123/orders

❌ GET /user
❌ GET /getUser
❌ GET /user/123

使用层次关系:

✅ GET /users/123/orders          # 特定用户的订单
✅ GET /teams/5/members           # 特定团队的成员
✅ POST /projects/10/tasks        # 在项目10中创建任务

❌ GET /userOrders/123            # 平坦结构
❌ GET /orders?userId=123         # 关系的查询参数

对多词资源使用kebab-case:

✅ /shopping-carts
✅ /order-items
✅ /user-preferences

❌ /shoppingCarts    (camelCase)
❌ /shopping_carts   (snake_case)
❌ /ShoppingCarts    (PascalCase)

HTTP方法(动词)

方法 目的 幂等 安全 示例
GET 检索资源 GET /users/123
POST 创建资源 POST /users
PUT 替换整个资源 PUT /users/123
PATCH 部分更新 否* PATCH /users/123
DELETE 移除资源 DELETE /users/123
HEAD 仅元数据(无正文) HEAD /users/123
OPTIONS 允许的方法 OPTIONS /users

*PATCH可以设计为幂等

状态代码

成功(2xx)

  • 200 OK:成功的GET、PUT、PATCH或DELETE
  • 201 Created:成功的POST(包括Location头部)
  • 202 Accepted:请求被接受,异步处理
  • 204 No Content:成功的DELETE或PUT无响应正文

客户端错误(4xx)

  • 400 Bad Request:无效的请求正文或参数
  • 401 Unauthorized:缺少或无效的身份验证
  • 403 Forbidden:已认证但未授权
  • 404 Not Found:资源不存在
  • 405 Method Not Allowed:HTTP方法不支持资源
  • 409 Conflict:资源冲突(例如,重复)
  • 422 Unprocessable Entity:验证失败
  • 429 Too Many Requests:速率限制超出

服务器错误(5xx)

  • 500 Internal Server Error:通用服务器错误
  • 502 Bad Gateway:上游服务错误
  • 503 Service Unavailable:暂时不可用
  • 504 Gateway Timeout:上游超时

请求/响应格式

请求正文(POST/PUT/PATCH):

POST /users
Content-Type: application/json

{
  "email": "jane@example.com",
  "name": "Jane Smith",
  "role": "developer"
}

成功响应:

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

{
  "id": 123,
  "email": "jane@example.com",
  "name": "Jane Smith",
  "role": "developer",
  "created_at": "2025-10-31T10:30:00Z",
  "updated_at": "2025-10-31T10:30:00Z"
}

错误响应(标准格式):

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "请求验证失败",
    "details": [
      {
        "field": "email",
        "message": "电子邮件已注册",
        "code": "DUPLICATE_EMAIL"
      },
      {
        "field": "name",
        "message": "名称至少2个字符",
        "code": "NAME_TOO_SHORT"
      }
    ],
    "timestamp": "2025-10-31T10:30:00Z",
    "request_id": "req_abc123"
  }
}

分页

基于游标的分页(推荐):

GET /users?cursor=eyJpZCI6MTIzfQ&limit=20

响应:
{
  "data": [...],
  "pagination": {
    "next_cursor": "eyJpZCI6MTQzfQ",
    "has_more": true
  }
}

优点:即使数据变化,结果也一致 用途:大数据集、实时数据、无限滚动

基于偏移量的分页:

GET /users?page=2&per_page=20

响应:
{
  "data": [...],
  "pagination": {
    "page": 2,
    "per_page": 20,
    "total": 487,
    "total_pages": 25
  }
}

优点:易于理解,支持“跳至第N页” 用途:小数据集、管理面板、已知界限

过滤和排序

过滤:

GET /users?status=active&role=developer&created_after=2025-01-01
GET /products?price_min=10&price_max=100&category=electronics

排序:

GET /users?sort=created_at:desc
GET /users?sort=-created_at              # 减号前缀表示降序
GET /users?sort=name:asc,created_at:desc # 多个字段

字段选择(部分响应):

GET /users?fields=id,name,email          # 仅指定字段
GET /users/123?exclude=password_hash     # 除了指定的之外全部

API版本控制

策略1:URI版本控制(推荐)

✅ /api/v1/users
✅ /api/v2/users

优点:清晰,易于测试,缓存友好
缺点:URL冗长

策略2:头部版本控制

GET /api/users
Accept: application/vnd.company.v2+json

优点:URL清晰
缺点:测试难度大,URL不可见

策略3:查询参数

GET /api/users?version=2

优点:简单
缺点:可能会被遗忘,与业务逻辑参数混合

最佳实践:公共API使用URI版本控制,内部服务使用头部版本控制

速率限制

响应头部:

HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1635724800

超出时的响应:
HTTP/1.1 429 Too Many Requests
Retry-After: 3600

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "API速率限制超出",
    "retry_after": 3600
  }
}

认证与授权

Bearer Token(JWT):

GET /users/me
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

API密钥:

GET /users
X-API-Key: sk_live_abc123...

基本认证(生产中避免使用):

GET /users
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

GraphQL API设计

架构设计原则

1. 默认可空

type User {
  id: ID!              # 非空(必需)
  email: String!       # 非空
  name: String         # 可空(可选)
  avatar: String       # 可空
}

2. 对列表使用连接

type Query {
  users(first: Int, after: String): UserConnection!
}

type UserConnection {
  edges: [UserEdge!]!
  pageInfo: PageInfo!
  totalCount: Int!
}

type UserEdge {
  node: User!
  cursor: String!
}

type PageInfo {
  hasNextPage: Boolean!
  hasPreviousPage: Boolean!
  startCursor: String
  endCursor: String
}

3. 为突变使用输入类型

input CreateUserInput {
  email: String!
  name: String!
  role: UserRole!
}

type Mutation {
  createUser(input: CreateUserInput!): CreateUserPayload!
}

type CreateUserPayload {
  user: User!
  errors: [UserError!]
}

type UserError {
  field: String!
  message: String!
  code: String!
}

查询设计

获取单个资源:

query GetUser {
  user(id: "123") {
    id
    name
    email
    posts {
      id
      title
    }
  }
}

获取带有过滤器的列表:

query GetUsers {
  users(
    first: 10
    after: "cursor123"
    filter: { role: DEVELOPER, status: ACTIVE }
  ) {
    edges {
      node {
        id
        name
        email
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

错误处理

字段级错误:

type Mutation {
  createUser(input: CreateUserInput!): CreateUserPayload!
}

type CreateUserPayload {
  user: User
  errors: [UserError!]
}

响应:

{
  "data": {
    "createUser": {
      "user": null,
      "errors": [
        {
          "field": "email",
          "message": "电子邮件已被占用",
          "code": "DUPLICATE_EMAIL"
        }
      ]
    }
  }
}

gRPC API设计

Proto文件结构

user.proto:

syntax = "proto3";

package company.user.v1;

import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";

// 用户服务定义
service UserService {
  // 通过ID获取用户
  rpc GetUser(GetUserRequest) returns (GetUserResponse);

  // 分页列出用户
  rpc ListUsers(ListUsersRequest) returns (ListUsersResponse);

  // 创建新用户
  rpc CreateUser(CreateUserRequest) returns (CreateUserResponse);

  // 更新用户
  rpc UpdateUser(UpdateUserRequest) returns (UpdateUserResponse);

  // 删除用户
  rpc DeleteUser(DeleteUserRequest) returns (google.protobuf.Empty);

  // 流更新(服务器流)
  rpc WatchUsers(WatchUsersRequest) returns (stream UserEvent);
}

// 消息
message User {
  string id = 1;
  string email = 2;
  string name = 3;
  UserRole role = 4;
  google.protobuf.Timestamp created_at = 5;
  google.protobuf.Timestamp updated_at = 6;
}

enum UserRole {
  USER_ROLE_UNSPECIFIED = 0;
  USER_ROLE_ADMIN = 1;
  USER_ROLE_DEVELOPER = 2;
  USER_ROLE_VIEWER = 3;
}

message GetUserRequest {
  string id = 1;
}

message GetUserResponse {
  User user = 1;
}

message ListUsersRequest {
  int32 page_size = 1;
  string page_token = 2;
  string filter = 3;  // 例如,"role=DEVELOPER AND status=ACTIVE"
}

message ListUsersResponse {
  repeated User users = 1;
  string next_page_token = 2;
  int32 total_size = 3;
}

message CreateUserRequest {
  string email = 1;
  string name = 2;
  UserRole role = 3;
}

message CreateUserResponse {
  User user = 1;
}

错误处理

使用gRPC状态代码:

// OK: 成功
// CANCELLED: 客户端取消
// INVALID_ARGUMENT: 无效请求(400等效)
// NOT_FOUND: 资源未找到(404等效)
// ALREADY_EXISTS: 重复(409等效)
// PERMISSION_DENIED: 禁止(403等效)
// UNAUTHENTICATED: 需要认证(401等效)
// RESOURCE_EXHAUSTED: 速率限制(429等效)
// INTERNAL: 服务器错误(500等效)

API文档

OpenAPI 3.1结构

参见/templates/openapi-template.yaml了解完整示例。

关键部分:

  • info: API元数据(标题、版本、描述)
  • servers: 不同环境的基础URL
  • paths: 端点与操作
  • components: 可重用的模式、响应、参数
  • security: 认证方案

AsyncAPI 3.0(事件驱动)

用于记录基于消息的API(Kafka、RabbitMQ、WebSocket)。

参见/templates/asyncapi-template.yaml了解完整示例。


最佳实践

1. 使用标准媒体类型

Content-Type: application/json          # JSON
Content-Type: application/xml           # XML
Content-Type: application/protobuf      # Protocol Buffers
Content-Type: application/octet-stream  # 二进制数据

2. HATEOAS(REST可选)

包含相关资源的链接:

{
  "id": 123,
  "name": "Jane Smith",
  "_links": {
    "self": { "href": "/users/123" },
    "orders": { "href": "/users/123/orders" },
    "avatar": { "href": "/users/123/avatar" }
  }
}

3. 幂等键

防止重复操作:

POST /payments
Idempotency-Key: unique-request-id-123

4. 批量操作

POST /users/bulk-create
POST /users/bulk-update
POST /users/bulk-delete

5. Webhooks

记录Webhook有效载荷和重试逻辑:

POST https://client.example.com/webhook
X-Webhook-Signature: sha256=abc123...

{
  "event": "user.created",
  "data": { ... },
  "timestamp": "2025-10-31T10:30:00Z"
}

常见陷阱

在URL中使用动词

不良:POST /createUser
良好:POST /users

不一致的命名

不良:/users, /userOrders, /user_preferences
良好:/users, /orders, /preferences

忽略HTTP方法

不良:POST /users/123/delete
良好:DELETE /users/123

暴露实现细节

不良:/users-table, /get-user-from-db
良好:/users, /users/123

通用错误消息

不良:{ "error": "Something went wrong" }
良好:{ "error": { "code": "DUPLICATE_EMAIL", "message": "电子邮件已存在" }}

与代理集成

后端系统架构师

  • 在设计新API时使用此框架
  • 参考模式以实现服务间的一致性
  • 从模板创建OpenAPI规范

前端UI开发人员

  • 实施前审查API合同
  • 提供开发者体验的反馈
  • 与遵循文档模式的API集成

代码质量审查员

  • 根据此框架验证API设计
  • 确保OpenAPI文档准确完整
  • 检查REST/GraphQL/gRPC最佳实践

技能版本:1.0.0 最后更新:2025-10-31 维护者:AI代理中心团队