- AI 技能
- AI 插件
- 人工智能
【免费下载链接】agentic-awesome-skills
AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.
本指南以 agentic-awesome-skills 仓库内 api-design-principles 技能包的 REST Best Practices 参考文档为骨架,系统梳理 REST API 设计的核心规范,并结合作者随包提供的 rest-api-template.py 与 api-design-checklist.md,给出可复制、可运行的生产级实现。读完本文,你将掌握资源命名、HTTP 语义、分页/过滤、版本化、限流、错误格式、缓存、幂等性、CORS、OpenAPI 文档与健康检查等一整套 REST 设计方法,并能在 FastAPI 中直接落地。
该技能包在仓库的 skills_index.json 中被登记为分类backend、风险等级safe、来源community,插件目标同时支持 codex 与 claude 两类 Agent(参见 skills_index.json),说明它属于面向开发者的通用 API 设计方法论,而非特定框架绑定,正文中的代码示例采用 FastAPI 仅作为演示载体。
一、URL 结构:资源命名与层级设计
1.1 资源命名:名词复数,杜绝动词
REST 将"资源"建模为名词,HTTP 方法表达操作语义,因此 URL 中不应出现动词。原文档给出了清晰的对照:
# Good - Plural nouns GET /api/users GET /api/orders GET /api/products # Bad - Verbs or mixed conventions GET /api/getUser GET /api/user (inconsistent singular) POST /api/createOrder配套的 api-design-checklist.md 在"Pre-Implementation Review → Resource Design"一节进一步固化了这条检查项:Resources are nouns, not verbs、Plural names for collections、Consistent naming across all endpoints,并建议把资源层级控制在 2 层以内(Clear resource hierarchy (avoid deep nesting >2 levels))。
1.2 嵌套资源:浅层优先
子资源通过嵌套表达从属关系,但嵌套过深会让 URL 冗长、路由复杂且难以维护:
# Shallow nesting (preferred) GET /api/users/{id}/orders GET /api/orders/{id} # Deep nesting (avoid) GET /api/users/{id}/orders/{orderId}/items/{itemId}/reviews # Better: GET /api/order-items/{id}/reviews设计要点:当子资源本身需要被独立寻址时(如order-item可以直接通过 ID 访问),应把它提升为顶层资源,用"提升实体"的方式打断过深的层级,而不是无限嵌套下去。
二、HTTP 方法与状态码语义
原文档对每个 HTTP 方法给出了完整的请求-响应映射,这也是 REST 契约中最重要的部分。
2.1 GET —— 检索资源(安全、幂等)
GET /api/users → 200 OK (with list) GET /api/users/{id} → 200 OK or 404 Not Found GET /api/users?page=2 → 200 OK (paginated)GET 必须是无副作用的;集合请求应支持分页(见第四节)。模板中的列表端点list_users正是按此模式实现,见 rest-api-template.py。
2.2 POST —— 创建资源
POST /api/users Body: {"name": "John", "email": "john@example.com"} → 201 Created Location: /api/users/123 Body: {"id": "123", "name": "John", ...} POST /api/users (validation error) → 422 Unprocessable Entity Body: {"errors": [...]}要点:
- 创建成功返回
201 Created,并在响应头Location中给出新资源的定位; - 校验失败返回
422 Unprocessable Entity而不是笼统的 400,因为请求语法本身合法,只是语义/业务校验不通过(如邮箱格式非法)。
模板中的create_user端点用status_code=status.HTTP_201_CREATED显式声明创建语义,并用 Pydantic 的EmailStr类型在请求进入业务逻辑前完成字段级校验,见 rest-api-template.py。
2.3 PUT —— 整体替换(幂等)
PUT /api/users/{id} Body: {complete user object} → 200 OK (updated) → 404 Not Found (doesn't exist) # Must include ALL fieldsPUT 要求客户端提交完整对象,服务端整体覆盖;重复提交同一 PUT 结果一致,因此天然幂等。
2.4 PATCH —— 部分更新
PATCH /api/users/{id} Body: {"name": "Jane"} (only changed fields) → 200 OK → 404 Not FoundPATCH 只携带发生变更的字段。模板中update_user的实现很好地演示了这一语义:用update.model_dump(exclude_unset=True)只取出客户端显式设置的字段,再逐项应用到既有对象上,避免把未传字段误置为空,见 rest-api-template.py。
2.5 DELETE —— 删除资源
DELETE /api/users/{id} → 204 No Content (deleted) → 404 Not Found → 409 Conflict (can't delete due to references)删除成功返回204 No Content(无响应体);若资源被外键/引用约束而无法删除,应返回409 Conflict说明状态冲突。模板中delete_user先调用get_user校验资源存在再返回 204,见 rest-api-template.py。
2.6 状态码速查表
原文档给出的完整状态码指南如下,这也是 api-design-checklist.md "Status Codes" 检查清单的直接依据:
| 状态码 | 语义 |
|---|---|
200 OK | 成功的 GET、PATCH、PUT |
201 Created | 成功的 POST |
204 No Content | 成功的 DELETE |
400 Bad Request | 请求格式错误 |
401 Unauthorized | 需要认证 |
403 Forbidden | 已认证但权限不足 |
404 Not Found | 资源不存在 |
409 Conflict | 状态冲突(如邮箱重复) |
422 Unprocessable Entity | 校验失败 |
429 Too Many Requests | 被限流 |
500 Internal Server Error | 服务端错误 |
503 Service Unavailable | 临时不可用 |
三、过滤、排序与搜索
集合端点通过查询参数承载过滤/排序/搜索能力,保持 URL 干净且语义明确:
# Filtering GET /api/users?status=active GET /api/users?role=admin&status=active # Sorting GET /api/users?sort=created_at GET /api/users?sort=-created_at (descending) GET /api/users?sort=name,created_at # Searching GET /api/users?search=john GET /api/users?q=john # Field selection (sparse fieldsets) GET /api/users?fields=id,name,email实现约定:排序参数用字段名前缀-表示降序,逗号分隔多级排序;搜索参数search/q对应全文检索;fields允许客户端按需选择返回字段(sparse fieldsets),减少传输体积。
模板中list_users端点把status(枚举过滤)与search(关键词搜索)直接建模为可选查询参数,并用 FastAPI 的Query附加约束(page >= 1、page_size介于 1 与 100 之间),见 rest-api-template.py。
四、分页模式
4.1 基于偏移量(Offset-Based)分页
适合中小规模数据集,实现简单:
GET /api/users?page=2&page_size=20 Response: { "items": [...], "page": 2, "page_size": 20, "total": 150, "pages": 8 }模板中通过PaginationParams(page默认 1、page_size默认 20、上限 100)与PaginatedResponse两个 Pydantic 模型固化了这套响应结构,页数计算采用向上取整(total + page_size - 1) // page_size,见 rest-api-template.py 与 rest-api-template.py。
4.2 基于游标(Cursor-Based)分页
适合大数据集与高频写入场景:游标编码了最后一条记录的位置,新数据插入不会导致页码漂移、重复或遗漏:
GET /api/users?limit=20&cursor=eyJpZCI6MTIzfQ Response: { "items": [...], "next_cursor": "eyJpZCI6MTQzfQ", "has_more": true }4.3 Link Header 分页(纯 RESTful 风格)
把分页导航放入 HTTP 响应头,响应体只含数据本身:
GET /api/users?page=2 Response Headers: Link: <https://api.example.com/users?page=3>; rel="next", <https://api.example.com/users?page=1>; rel="prev", <https://api.example.com/users?page=1>; rel="first", <https://api.example.com/users?page=8>; rel="last"选择哪种模式应在设计期定下来:api-design-checklist.md 的 Pagination 检查项要求所有集合端点均分页、明确默认页大小与上限、携带分页元数据,并"选择 cursor 或 offset 模式之一"。
五、版本化策略
版本化是 API 演进的护栏。原文档给出三种主流方案及其取舍:
URL 版本化(推荐)
/api/v1/users /api/v2/users Pros: Clear, easy to route Cons: Multiple URLs for same resourceHeader 版本化
GET /api/users Accept: application/vnd.api+json; version=2 Pros: Clean URLs Cons: Less visible, harder to test查询参数版本化
GET /api/users?version=2 Pros: Easy to test Cons: Optional parameter can be forgotten原文档明确推荐 URL 版本化——它直观、易于路由与缓存区分。api-design-checklist.md 同时要求:定义版本化策略(URL/header/query 三选一)、所有端点包含版本、并书面化弃用(deprecation)政策。
六、限流(Rate Limiting)
6.1 限流响应头
标准限流头让客户端可以主动感知配额:
X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 742 X-RateLimit-Reset: 1640000000 Response when limited: 429 Too Many Requests Retry-After: 3600被限流时必须返回429,并附Retry-After指示客户端多久后重试。
6.2 滑动窗口实现模式
原文档给出了一个可直接运行的固定窗口/滑动窗口限流器:
from fastapi import HTTPException, Request from datetime import datetime, timedelta class RateLimiter: def __init__(self, calls: int, period: int): self.calls = calls self.period = period self.cache = {} def check(self, key: str) -> bool: now = datetime.now() if key not in self.cache: self.cache[key] = [] # Remove old requests self.cache[key] = [ ts for ts in self.cache[key] if now - ts < timedelta(seconds=self.period) ] if len(self.cache[key]) >= self.calls: return False self.cache[key].append(now) return True limiter = RateLimiter(calls=100, period=60) @app.get("/api/users") async def get_users(request: Request): if not limiter.check(request.client.host): raise HTTPException( status_code=429, headers={"Retry-After": "60"} ) return {"users": [...]}该实现以客户端 IP(request.client.host)为限流键,在窗口内裁剪过期时间戳并计数。它演示了限流的完整形态;生产环境建议换用 Redis 等集中式存储以支持多实例部署。api-design-checklist.md 的 Rate Limiting 检查项包括:按端点/用户定义限额、返回限流头、超限返回 429、提供Retry-After。
七、认证与授权
Authorization: Bearer eyJhbGciOiJIUzI1NiIs... 401 Unauthorized - Missing/invalid token 403 Forbidden - Valid token, insufficient permissionsX-API-Key: your-api-key-here两条核心区分原则:
401 Unauthorized:认证缺失或令牌无效(你是谁?);403 Forbidden:令牌有效但权限不足(你能干什么?)。
两种常见机制:Bearer Token(JWT 等,承载身份与声明)与 API Key(常用于服务间调用/第三方集成,通过X-API-Key头传递)。api-design-checklist.md 的检查项要求在所有端点实施授权检查、正确区分 401/403、并处理令牌过期。
八、统一错误响应格式
8.1 错误响应结构
所有错误返回一致的 JSON 结构,客户端才能可靠解析:
{ "error": { "code": "VALIDATION_ERROR", "message": "Request validation failed", "details": [ { "field": "email", "message": "Invalid email format", "value": "not-an-email" } ], "timestamp": "2025-10-16T12:00:00Z", "path": "/api/users" } }字段设计要点:
code:机器可读的错误码,便于客户端程序化处理;message:人类可读的概括;details:字段级错误明细(含字段名、原因、错误值);timestamp/path:便于定位与排查。
模板通过 Pydantic 模型与全局异常处理器把这一格式固化为统一出口:ErrorDetail(field/message/code)与ErrorResponse(error/message/details),并在http_exception_handler中把任何HTTPException统一转换成该 JSON 形态,见 rest-api-template.py。404 场景在get_user中以detail={"message": "User not found", "details": {"id": user_id}}演示了带明细的错误构造,见 rest-api-template.py。
8.2 状态码选用指南
上文 2.6 节的状态码表就是错误语义的骨架。补充两点:409 Conflict适用于"状态冲突"(如注册重复邮箱);422专用于字段/业务校验失败。这两者与 400(语法错误)要区分开。
九、缓存策略
9.1 缓存头
# Client caching Cache-Control: public, max-age=3600 # No caching Cache-Control: no-cache, no-store, must-revalidate # Conditional requests ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4" If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4" → 304 Not ModifiedCache-Control:声明可缓存性与有效期;ETag:资源内容的指纹;客户端带If-None-Match发起条件请求,服务端比对未变化时返回304 Not Modified(无响应体),显著节省带宽。
注意区分两类缓存:客户端/CDN 缓存(上述头)与服务端缓存(如对高频只读查询做内存/Redis 缓存)。api-design-checklist.md 的 Performance 检查项同时覆盖"缓存策略定义"与"缓存头正确设置"。
十、批量操作
当单次请求需要操作多条记录时,提供专用批量端点,避免客户端发 N 次请求:
POST /api/users/batch { "items": [ {"name": "User1", "email": "user1@example.com"}, {"name": "User2", "email": "user2@example.com"} ] } Response: { "results": [ {"id": "1", "status": "created"}, {"id": null, "status": "failed", "error": "Email already exists"} ] }批量响应必须逐条报告成功/失败,而不是整体成功或整体失败,以便客户端精确定位失败项并重试。
十一、幂等性(Idempotency)
对容易因重试而重复执行的写操作(典型如创建订单),引入幂等键:
POST /api/orders Idempotency-Key: unique-key-123 If duplicate request: → 200 OK (return cached response)客户端为一次业务操作生成唯一键;服务端收到重复键时直接返回首次处理的结果(通常缓存该响应),从而在网络重试、客户端重发等场景下保证业务结果不重复。POST(默认非幂等)+ 幂等键组合是支付、下单等场景的标准实践;PUT/DELETE 本身就幂等,通常无需幂等键。
十二、CORS 配置
跨域访问是浏览器端调用的必答题。模板给出了 FastAPI 的 CORS 中间件配置并附生产注意事项:
from fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins=["https://example.com"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], )rest-api-template.py 中提供了更保守的默认版:allow_origins=["*"]且allow_credentials=False,并明确注释了生产化要求——使用具体来源列表;如需携带 Cookie/认证头则开启allow_credentials=True但必须收紧allow_origins(通配符*与凭据不能同时安全使用)。同一文件还启用了TrustedHostMiddleware以防 HTTP Host 头攻击,见 rest-api-template.py。
十三、用 OpenAPI 驱动文档
FastAPI 从类型注解自动生成 OpenAPI/Swagger 文档,让文档与实现永不脱节:
from fastapi import FastAPI app = FastAPI( title="My API", description="API for managing users", version="1.0.0", docs_url="/docs", redoc_url="/redoc" ) @app.get( "/api/users/{user_id}", summary="Get user by ID", response_description="User details", tags=["Users"] ) async def get_user( user_id: str = Path(..., description="The user ID") ): """ Retrieve user by ID. Returns full user profile including: - Basic information - Contact details - Account status """ pass文档化实践包括:summary/response_description描述端点意图,tags分组,Path(..., description=...)描述路径参数,docstring 说明响应内容。模板中app = FastAPI(title="API Template", version="1.0.0", docs_url="/api/docs")与各端点的tags=["Users"]正是这套实践,见 rest-api-template.py。api-design-checklist.md 的 Documentation 检查项要求:生成 OpenAPI/Swagger 规范、所有端点有文档、提供请求/响应示例、文档化错误响应与认证流程。
十四、健康与监控端点
运维可观测性的最低要求是健康检查:
@app.get("/health") async def health_check(): return { "status": "healthy", "version": "1.0.0", "timestamp": datetime.now().isoformat() } @app.get("/health/detailed") async def detailed_health(): return { "status": "healthy", "checks": { "database": await check_database(), "redis": await check_redis(), "external_api": await check_external_api() } }设计约定:/health用于负载均衡/编排系统的存活探测(轻量、只报整体状态与版本时间戳);/health/detailed面向人工排查,逐项报告数据库、Redis、外部 API 等依赖的连通性。api-design-checklist.md 的 Monitoring 检查项也把"健康检查端点可用"列为必需。
十五、把这些规范落地为一次设计评审
原文档的规范与其配套清单形成了可执行的评审流程,建议在设计或评审 API 时按以下次序过一遍:
- 资源设计:名词复数、集合命名一致、层级 ≤ 2、CRUD 与 HTTP 方法正确映射;
- HTTP 语义:GET 安全幂等、POST 创建返回 201、PUT 整体替换、PATCH 部分更新、DELETE 返回 204;
- 状态码:严格按 2.6 节表格选用,尤其区分 400/401/403/404/409/422/429;
- 分页与过滤:集合端点全部分页、明确默认值与上限、携带分页元数据,选 offset 或 cursor 其一;
- 版本化:选定策略(推荐 URL 版本化)并书面化弃用政策;
- 错误格式:统一错误结构、字段级明细、错误码、时间戳;
- 认证授权:定义认证方式、全端点授权检查、正确区分 401/403;
- 限流:定义配额、返回限流头、429 + Retry-After;
- 文档与测试:OpenAPI 自动生成、错误场景与边界用例覆盖;
- 安全与性能:输入校验、SQL 注入/XSS 防护、CORS 收紧、HTTPS、查询优化与 N+1 预防、缓存与监控就绪。
以上每一条都可以在 api-design-checklist.md 中找到对应的勾选项(该清单还额外覆盖 GraphQL 专用检查项:Schema 优先、查询深度/复杂度限制、DataLoader 防 N+1、Relay 分页、持久化查询等),并可用 rest-api-template.py 作为骨架快速搭建符合规范的 FastAPI 服务——在仓库中执行uvicorn运行该模板(见文件尾部入口 rest-api-template.py)即可本地验证本文所述的分页、过滤、错误处理与文档生成行为。
- AI 技能
- AI 插件
- 人工智能
【免费下载链接】agentic-awesome-skills
AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,600+ agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.
相关推荐
MaterialColorsApp与主流设计工具集成:Figma、Sketch、Adobe XD工作流
MaterialColorsApp与主流设计工具集成:Figma、Sketch、Adobe XD工作流 MaterialColorsApp是一款便捷的Mac应用
agentic-awesome-skills 实战:基于 FastAPI 模板构建生产级 Python REST API 的完整指南
agentic awesome skills 实战:基于 FastAPI 模板构建生产级 Python REST API 的完整指南 导读 本文以 agenti
AI 技能AI 插件人工智能agentic-awesome-skills 之 API 设计原则实战手册:REST 与 GraphQL 的工程化落地指南
agentic awesome skills 之 API 设计原则实战手册:REST 与 GraphQL 的工程化落地指南 本指南以 implementatio
AI 技能AI 插件人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考