mcpField
A
api-design-ops

api-design-ops

github.com/0xdarkmatter开发7838 次安装2 周前更新
代码仓库

关于 api-design-ops

API Design Ops 是面向生产级 API 开发者的设计参考技能,涵盖 REST、gRPC 和 GraphQL。它结合风格选择指南与错误处理、分页、安全和版本管理等常见问题的设计模式。

主要功能

  1. 01REST、gRPC 和 GraphQL 指南
  2. 02API 风格选择框架
  3. 03资源建模与分页模式
  4. 04错误处理与版本管理指南
  5. 05身份验证和限流模式
  6. 06安全与性能参考资料

适用场景

  1. 01为服务选择 API 风格
  2. 02设计统一的错误响应
  3. 03规划分页与版本管理
  4. 04评估 API 安全方案

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/0xdarkmatter/claude-mods --skill api-design-ops

安装后在 Claude Code 中输入/api-design-ops确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
.gitkeep
references/
api-security.md
graphql.md
grpc.md
rest-advanced.md
scripts/
.gitkeep

详细介绍

API 设计运维

全面介绍 REST(进阶)、gRPC 和 GraphQL 的 API 设计模式。本技能提供决策框架、设计模式和实施指南,助力构建适用于生产环境的 API。

API 风格决策树

What kind of API do you need?
|
+-- Internal microservice-to-microservice?
|   +-- High throughput, low latency needed? --> gRPC
|   +-- Streaming (real-time data, logs)? --> gRPC (bidirectional streaming)
|   +-- Simple request/response, team comfort? --> REST
|
+-- Public-facing API?
|   +-- Third-party developers consuming it? --> REST (widest compatibility)
|   +-- Mobile app with varied data needs? --> GraphQL
|   +-- Browser-only, simple CRUD? --> REST
|
+-- Frontend for your own app?
|   +-- Multiple clients with different data shapes? --> GraphQL
|   +-- Single client, straightforward data? --> REST
|   +-- Real-time updates needed? --> GraphQL subscriptions or SSE
|
+-- IoT / embedded / constrained devices?
|   +-- Binary efficiency matters? --> gRPC
|   +-- HTTP-only environments? --> REST
快速比较
关注点RESTgRPCGraphQL
传输方式HTTP/1.1+HTTP/2HTTP(任意)
序列化JSON(文本)Protobuf(二进制)JSON(文本)
SchemaOpenAPI(可选).proto(必需)SDL(必需)
浏览器支持原生通过 gRPC-Web/Connect原生
缓存内置 HTTP 缓存自定义自定义(规范化)
学习曲线低中中高
代码生成可选必需可选,但推荐
流式传输SSE、WebSocket原生(4 种模式)订阅
过度获取常见问题不会(强类型)通过设计解决
文件上传原生支持 Multipart分块流式传输Multipart 规范(不够理想)

REST 资源设计速查

资源命名
GET    /users                  # Collection
GET    /users/{id}             # Singleton
GET    /users/{id}/orders      # Sub-collection
POST   /users                  # Create
PUT    /users/{id}             # Full replace
PATCH  /users/{id}             # Partial update
DELETE /users/{id}             # Remove

# Naming rules:
# - Plural nouns for collections: /users NOT /user
# - Kebab-case for multi-word: /line-items NOT /lineItems
# - No verbs in URLs: POST /orders NOT POST /create-order
# - Max 3 levels deep: /users/{id}/orders (not /users/{id}/orders/{oid}/items/{iid}/details)
HTTP 方法和状态码
方法成功空无效未找到冲突
GET200200(空数组)400404-
POST201 + Location-400/422-409
PUT200-400/422404409
PATCH200-400/422404409
DELETE204204(已不存在)400404409
HATEOAS(何时值得采用)

适用于:重视可发现性的公共 API、长期运行的 API、频繁演进的 API。 不适用于:内部微服务、移动端后端、可接受紧耦合的场景。

{
  "id": "order-123",
  "status": "shipped",
  "_links": {
    "self": { "href": "/orders/order-123" },
    "track": { "href": "/orders/order-123/tracking" },
    "cancel": { "href": "/orders/order-123", "method": "DELETE" }
  }
}

分页决策树

What's your data like?
|
+-- Stable data, UI needs "jump to page 5"?
|   --> Offset pagination: ?page=5&per_page=20
|   Tradeoff: Slow on large offsets (OFFSET 10000), inconsistent with inserts
|
+-- Large dataset, forward-only traversal?
|   --> Cursor pagination: ?after=eyJpZCI6MTIzfQ&limit=20
|   Tradeoff: No random page access, but consistent and fast
|
+-- Real-time feed, ordered by timestamp or ID?
|   --> Keyset pagination: ?created_after=2024-01-01T00:00:00Z&limit=20
|   Tradeoff: Requires a unique, sequential column; no page jumping
响应封装
{
  "data": [...],
  "pagination": {
    "total": 1432,
    "limit": 20,
    "has_more": true,
    "next_cursor": "eyJpZCI6MTQzMn0="
  }
}

错误响应格式(RFC 7807)

所有 API 都应使用 Problem Details(RFC 7807 / RFC 9457):

{
  "type": "https://api.example.com/errors/insufficient-funds",
  "title": "Insufficient Funds",
  "status": 422,
  "detail": "Account xxxx-1234 has a balance of $10.00, but the transfer requires $25.00.",
  "instance": "/transfers/txn-abc-123",
  "balance": 1000,
  "required": 2500
}
字段参考
字段必需说明
type是用于标识错误类型的 URI(稳定且可记录)
title是面向用户的摘要(此类型的所有实例均相同)
status是HTTP 状态码
detail是针对此次错误的面向用户说明
instance否用于标识具体错误实例的 URI
(扩展字段)否其他机器可读字段
验证错误
{
  "type": "https://api.example.com/errors/validation",
  "title": "Validation Failed",
  "status": 422,
  "detail": "The request body contains 2 validation errors.",
  "errors": [
    { "field": "email", "message": "Must be a valid email address", "code": "invalid_format" },
    { "field": "age", "message": "Must be at least 18", "code": "out_of_range", "min": 18 }
  ]
}

版本控制策略

策略示例优点缺点
URL 路径/v2/users清晰、可缓存、路由简单URL 冗杂,难以停用
Accept 标头Accept: application/vnd.api.v2+jsonURL 简洁,支持内容协商不明显,较难测试
查询参数/users?version=2易于添加污染查询字符串,存在缓存问题
基于日期API-Version: 2024-01-15可进行细粒度演进(Stripe 风格)实施复杂
建议
  • 公共 API:采用 URL 路径版本控制(/v1/)——简单至上
  • 内部 API:使用标头或不进行版本控制(同步部署)
  • 持续演进的 API:如果有相应的工程投入,可采用基于日期的版本控制(Stripe 模式)
破坏性变更规则

凡可能导致现有客户端失效的变更,均属于破坏性变更:

  • 从响应中删除字段
  • 重命名字段
  • 更改字段类型
  • 在请求中添加必填字段
  • 更改 URL 结构
  • 更改错误格式
  • 删除端点

非破坏性(安全)变更:

  • 在请求中添加可选字段
  • 在响应中添加字段
  • 添加新端点
  • 添加新的枚举值(前提是客户端能够处理未知值)

速率限制设计

算法
算法行为适用场景
令牌桶允许突发请求,以稳定速率补充令牌通用 API 速率限制
滑动窗口分布平滑,不允许突发需要严格公平性
固定窗口简单,但可能在窗口边界出现突发低风险限制
漏桶恒定输出速率队列处理
响应头
X-RateLimit-Limit: 1000          # Max requests per window
X-RateLimit-Remaining: 743       # Requests left in current window
X-RateLimit-Reset: 1672531200    # Unix timestamp when window resets
Retry-After: 30                  # Seconds to wait (on 429)
429 响应正文
{
  "type": "https://api.example.com/errors/rate-limit-exceeded",
  "title": "Rate Limit Exceeded",
  "status": 429,
  "detail": "You have exceeded 1000 requests per hour. Try again in 30 seconds.",
  "retry_after": 30
}

幂等性

哪些方法需要幂等键?
方法按规范是否幂等?是否需要键?
GET是否
PUT是否(完整替换天然具有幂等性)
DELETE是否
PATCH否关键操作建议使用
POST否是(支付、订单和转账始终需要)
实现
POST /payments
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json

{ "amount": 2500, "currency": "usd", "customer": "cust_123" }

服务端:

  1. 接收带有 Idempotency-Key 请求头的请求
  2. 检查存储中(Redis、DB)是否存在该键
  3. 如果存在:返回已存储的响应(相同的状态码 + 正文)
  4. 如果不存在:处理请求,并以幂等键为键存储响应
  5. 键在 24-48 小时后过期

身份验证概览

方法使用场景安全级别
API Key服务间通信、内部场景、简单场景低-中
JWT (Bearer)无状态身份验证、微服务中-高
OAuth2 + PKCE第三方访问、用户委托高
mTLS服务网格、零信任基础设施非常高
决策指南
Who is authenticating?
|
+-- Your own frontend? --> JWT (short-lived access + refresh token)
+-- Third-party developer? --> OAuth2 (client credentials for server, PKCE for SPA)
+-- Another internal service? --> mTLS or JWT with service accounts
+-- Quick prototype? --> API key (but plan migration)

常见问题表

常见问题问题预防措施
“非破坏性”版本中的破坏性变更客户端崩溃仅允许增量变更的策略、契约测试
REST API 中的 N+1 问题100 个用户 = 101 次查询复合文档、?include= 或 GraphQL
过度获取移动端获取 50 个字段,但只需要 3 个稀疏字段集 ?fields=id,name 或 GraphQL
获取不足构建一个视图需要 3 次请求复合端点或 BFF 模式
CORS 配置错误前端无法访问 API明确指定允许的源,携带凭据时绝不使用 *
缺少 Content-Type415 或解析静默失败在每个变更端点上验证 Content-Type
大型负载未分页OOM、超时始终对集合分页,并设置最大页面大小
日期格式不一致解析混乱全面使用 ISO 8601:2024-01-15T10:30:00Z
没有请求 ID无法调试生成 X-Request-ID,并在服务间传递
枚举演进新值导致旧客户端出错说明枚举可能增加值,客户端必须处理未知值
缺少幂等性重复扣款、重复创建订单所有有副作用的 POST 端点都使用幂等键
查询复杂度不受限GraphQL DoS限制深度、分析成本、使用持久化查询

参考文件

文件内容
references/rest-advanced.md资源建模、PATCH 策略、缓存、webhook、批量操作
references/grpc.mdProtobuf、服务定义、Go/Rust、流式传输、错误处理
references/graphql.mdSchema 设计、解析器、DataLoader、联邦、性能
references/api-security.mdJWT、OAuth2、CORS、速率限制、OWASP API Top 10

评论

支持 Markdown