十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于 agentic-awesome-skills 的 API 设计原则实战指南:REST 与 GraphQL 的可维护性设计全流程

基于 agentic-awesome-skills 的 API 设计原则实战指南:REST 与 GraphQL 的可维护性设计全流程 AI 技能AI 插件【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,400 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址https://gitcode.com/gh_mirrors/an/agentic-awesome-skills点击查看免费下载导读本指南以 agentic-awesome-skills 仓库中 api-design-principles 技能 为核心骨架展开系统讲解从需求定义、风格选型、契约建模到错误处理、版本化、分页与鉴权策略的完整 API 设计方法论。读完本文你将掌握一套可直接落地到团队评审与编码环节的 REST/GraphQL 设计检查清单并能结合仓库提供的 FastAPI 可运行模板把设计规范转化为可执行的接口实现。一、技能定位何时使用、何时避免该技能面向接口契约设计这一层而非具体框架的实现细节。它定义了清晰的适用边界适用场景Use this skill when设计新的 REST 或 GraphQL API重构既有 API 以提升可用性为团队建立 API 设计标准在实现前评审 API 规范在 API 范式之间迁移如 REST 迁移到 GraphQL编写对开发者友好的 API 文档针对特定使用场景移动端、第三方集成优化 API。不适用场景Do not use this skill when只需要某个特定框架的实现指导只做基础设施工作、不涉及 API 契约无法修改或对公共接口做版本化。这一用/不用二分法非常关键API 设计决策一旦进入公共契约阶段改动成本极高因此技能在源头上就提示使用者只有当你拥有接口变更权与版本演进空间时才应启动这套流程。设计产出的边界在 SKILL.md 中有明确约束它不能替代环境特定的验证、测试与专家评审当关键输入需求、权限、安全边界、成功标准缺失时应停下询问而不是凭猜测继续。二、四步设计工作流从消费者定义到一致性评审技能把 API 设计收敛为一个可重复的四步流程每一步都有明确的产出物定义消费者、使用场景与约束Define consumers, use cases, and constraints。先回答谁在用、怎么用、限制是什么是移动端弱网场景还是服务端高频调用是第三方公开集成还是内部微服务约束包括吞吐、延迟、数据规模、合规要求等。这一步骤决定了后续所有取舍的依据。选择 API 风格并建模资源或类型Choose API style and model resources or types。在 REST 与 GraphQL 之间做范式选择然后建模REST 用名词化资源 HTTP 方法表达操作GraphQL 用类型系统Type/Interface/Union/Input表达领域模型。明确错误、版本化、分页与鉴权策略Specify errors, versioning, pagination, and auth strategy。这是公共契约中变不了的部分必须在实现前定稿统一的错误响应结构、可执行的版本演进策略、稳定的分页约定、清晰的鉴权/授权边界。用示例验证并做一致性评审Validate with examples and review for consistency。用真实请求/响应示例跑通每个端点并对照 api-design-checklist.md 逐项检查命名、状态码、分页、错误、安全等维度的一致性。仓库为这套流程准备了三个可复用的落地资产对应工作流的不同阶段references/rest-best-practices.mdREST 细则、references/graphql-schema-design.mdGraphQL 模式库与assets/api-design-checklist.md评审清单、assets/rest-api-template.py可运行模板下文逐一展开。三、REST API 设计核心规范rest-best-practices.md 提供了完整的 REST 设计细则覆盖从 URL 到监控的全生命周期。3.1 URL 结构与资源命名资源必须是复数名词禁止用动词表达操作命名在整个 API 中保持一致# 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嵌套资源遵循浅嵌套优先原则GET /api/users/{id}/orders这样的两级关系可以接受但超过两级的深层嵌套应当被拍平——把深层项提升为顶层资源通过查询参数关联# Deep nesting (avoid) GET /api/users/{id}/orders/{orderId}/items/{itemId}/reviews # Better: GET /api/order-items/{id}/reviews3.2 HTTP 方法与状态码映射每个方法承担单一语义且必须保持幂等性预期方法语义幂等典型响应GET检索是安全200 OK / 404 Not FoundPOST创建否201 Created带Location头PUT整体替换是200 OK / 404PATCH部分更新否200 OKDELETE删除是204 No Content / 404 / 409 Conflict创建成功时必须返回201 Created并携带Location: /api/users/123校验失败返回422 Unprocessable EntityDELETE 因存在外键引用无法删除时返回409 Conflict。3.3 过滤、排序与搜索统一使用查询参数表达三种能力命名稳定可预测# Filtering GET /api/users?statusactive GET /api/users?roleadminstatusactive # Sorting负号表示降序逗号表示多字段 GET /api/users?sortcreated_at GET /api/users?sort-created_at GET /api/users?sortname,created_at # Searching GET /api/users?searchjohn # Field selection稀疏字段集 GET /api/users?fieldsid,name,email3.4 三种分页模式与选型Offset 分页适合中小数据集响应中必须包含分页元数据total/page/pages默认页大小与上限要显式定义例如默认 20、上限 100GET /api/users?page2page_size20 # Response: { items: [...], page: 2, page_size: 20, total: 150, pages: 8 }Cursor 分页适合大数据集与无限滚动以不透明游标代替页码避免插入/删除导致的结果漂移GET /api/users?limit20cursoreyJpZCI6MTIzfQ # Response: { items: [...], next_cursor: eyJpZCI6MTQzfQ, has_more: true }Link Header 分页是纯 RESTful 风格把导航信息放进响应头而不是业务字段Link: https://api.example.com/users?page3; relnext, https://api.example.com/users?page1; relprev, https://api.example.com/users?page1; relfirst, https://api.example.com/users?page8; rellast3.5 版本化策略对比参考文档给出了三种策略及权衡策略示例优点缺点URL 版本化推荐/api/v1/users清晰、易路由同一资源多个 URLHeader 版本化Accept: application/vnd.apijson; version2URL 干净不直观、难测试Query 参数?version2易测试可选参数易被遗忘3.6 限流头部约定与实现模式限流信息应通过标准响应头暴露超限时返回429 Too Many Requests并附带Retry-AfterX-RateLimit-Limit: 1000 X-RateLimit-Remaining: 742 X-RateLimit-Reset: 1640000000 # Limited: 429 Too Many Requests Retry-After: 3600参考文档给出了一个基于内存时间窗的可运行实现核心是滑动窗口去旧加新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(secondsself.period) ] if len(self.cache[key]) self.calls: return False self.cache[key].append(now) return True limiter RateLimiter(calls100, period60) app.get(/api/users) async def get_users(request: Request): if not limiter.check(request.client.host): raise HTTPException( status_code429, headers{Retry-After: 60} ) return {users: [...]}3.7 认证与授权401 vs 403认证你是谁与授权你能干什么必须严格区分401 Unauthorized表示缺失或无效的 Token未认证403 Forbidden表示 Token 有效但权限不足已认证未授权。Authorization: Bearer eyJhbGciOiJIUzI1NiIs... # Bearer Token X-API-Key: your-api-key-here # API Key3.8 统一错误响应结构错误响应必须稳定、结构化、可被客户端程序化处理包含错误码、人类可读消息、字段级详情、时间戳与路径{ 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 } }完整状态码速查表200 表示 GET/PATCH/PUT 成功201 表示 POST 成功204 表示 DELETE 成功400 请求格式错误401 需要认证403 已认证但无权限404 资源不存在409 状态冲突如重复邮箱422 校验失败429 被限流500 服务端错误503 临时不可用。3.9 缓存、批量、幂等、CORS缓存通过Cache-Control控制客户端缓存用ETagIf-None-Match实现条件请求命中时返回304 Not ModifiedCache-Control: public, max-age3600 ETag: 33a64df551425fcc55e4d42a148795d9f25f89d4 If-None-Match: 33a64df551425fcc55e4d42a148795d9f25f89d4 → 304 Not Modified批量端点批量操作返回逐条结果状态允许部分成功POST /api/users/batch {items: [{name: User1, email: user1example.com}, ...]} # Response: {results: [{id: 1, status: created}, {id: null, status: failed, error: Email already exists}]}幂等键POST 类非幂等操作通过Idempotency-Key头实现重试安全重复请求返回首次缓存响应而非重复执行。CORS生产环境必须显式限定allow_origins只有确需携带 Cookie/鉴权头时才开allow_credentialsTrue此时禁止通配符来源。3.10 OpenAPI 文档与健康检查FastAPI 天然把设计即文档落在实处FastAPI(title..., version..., docs_url/api/docs, redoc_url/redoc)自动生成交互式文档每个端点用summary、response_description、tags与 docstring 丰富契约语义。健康检查应区分浅层与深层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()}}四、GraphQL Schema 设计模式graphql-schema-design.md 给出了从 Schema 组织到性能防护的完整模式库。GraphQL 的核心挑战是把灵活查询控制在安全边界内因此本节的每条模式都同时回答怎么设计与怎么防滥用。4.1 Schema 组织与模块化按领域拆分 Schema 文件用extend type归并 Query/Mutation 根类型避免巨型单文件# user.graphql type User { id: ID!, email: String!, name: String!, posts: [Post!]! } extend type Query { user(id: ID!): User users(first: Int, after: String): UserConnection! } extend type Mutation { createUser(input: CreateUserInput!): CreateUserPayload! }4.2 类型设计四件套非空 vs 可空id: ID!、email: String!表示必有字段phone: String表示可空posts: [Post!]!是非空数组内含非空元素tags: [String!]是可空数组内含非空字符串。经验法则是从可空开始当业务保证存在时再升级为非空避免 schema 变更炸掉客户端。Interface 表达多态公共字段id/createdAt抽到接口各类型implements NodeQuery 返回接口类型interface Node { id: ID!, createdAt: DateTime! } type User implements Node { id: ID!, createdAt: DateTime!, email: String! } type Post implements Node { id: ID!, createdAt: DateTime!, title: String! } type Query { node(id: ID!): Node }Union 表达异构结果搜索这类返回不同类型混合的场景用 union配合内联片段消费union SearchResult User | Post | Comment { search(query: graphql) { ... on User { name email } ... on Post { title content } ... on Comment { text author { name } } } }Input Type所有 mutation 参数必须封装为 input 类型支持嵌套 input如profileInput: ProfileInput更新场景用全可选 input 表达部分更新。4.3 分页Relay Cursor 连接模型大数据集推荐 Relay Cursor 连接模型edges/node/cursor加pageInfo客户端用first/after与last/before双向翻页type UserConnection { edges: [UserEdge!]! pageInfo: PageInfo! totalCount: Int! } type UserEdge { node: User!, cursor: String! } type PageInfo { hasNextPage: Boolean!, hasPreviousPage: Boolean! startCursor: String, endCursor: String } type Query { users(first: Int, after: String, last: Int, before: String): UserConnection! }简单场景可用 offset 分页page/pageSize/items/total但无限滚动场景应首选游标。4.4 Mutation 设计三模式Input/Payload 模式mutation 接收input返回payloadpayload 内嵌errors与success错误不依赖 GraphQL 传输层异常input CreatePostInput { title: String!, content: String!, tags: [String!] } type CreatePostPayload { post: Post errors: [Error!] success: Boolean! } type Mutation { createPost(input: CreatePostInput!): CreatePostPayload! }乐观响应支持payload 携带clientMutationId让客户端把服务端回执映射回本地乐观 UI 状态。批量 Mutation返回逐条结果、成功数与失败数type BatchCreateUserPayload { results: [CreateUserResult!]! successCount: Int!, errorCount: Int! } type CreateUserResult { user: User, errors: [Error!], index: Int! }4.5 字段参数、计算字段与订阅字段参数按分页/过滤/排序/搜索分组声明用 enum 限定排序键与方向计算字段postCount、isLikedByViewer在 resolver 中按需计算避免加载全量关联数据。实时场景用 Subscription可携带参数做定向推送如postUpdated(postId: ID!)。4.6 自定义标量与指令领域类型用自定义标量表达避免 String 滥用scalar DateTime / Email / URL / JSON / Money。内置指令deprecated标记退役字段、include(if:)做条件字段自定义指令可用于声明式鉴权directive auth(requires: Role USER) on FIELD_DEFINITION enum Role { USER ADMIN MODERATOR } type Mutation { deleteUser(id: ID!): Boolean! auth(requires: ADMIN) updateProfile(input: ProfileInput!): User! auth }4.7 GraphQL 错误处理Union 错误模式与 Payload 错误查询场景用Union 错误模式——把错误建模为一等类型并入返回联合客户端用内联片段区分成功与各错误分支union UserResult User | ValidationError | NotFoundError | AuthorizationError type Query { user(id: ID!): UserResult! }变更场景用Payload 错误模式见 4.4错误码用 enum 约束VALIDATION_ERROR / UNAUTHORIZED / NOT_FOUND / INTERNAL_ERROR。4.8 N1 与查询防护DataLoader是 N1 的标准解按关系批量加载并做内存缓存resolver 中从 context 取 loader 批量读取避免逐条查库class PostLoader(DataLoader): async def batch_load_fn(self, post_ids): posts await db.posts.find({id: {$in: post_ids}}) post_map {post[id]: post for post in posts} return [post_map.get(pid) for pid in post_ids]查询深度限制防递归炸弹与查询复杂度分析列表字段按大小参数加权双管齐下def depth_limit_validator(max_depth: int): def validate(context, node, ancestors): depth len(ancestors) if depth max_depth: raise GraphQLError(fQuery depth {depth} exceeds maximum {max_depth}) return validate def complexity_limit_validator(max_complexity: int): def calculate_complexity(node): complexity 1 if is_list_field(node): complexity * get_list_size_arg(node) return complexity return validate_complexity4.9 Schema 版本演进GraphQL 的演进哲学是永远别删只废弃新增可选字段向后兼容v1→v2替换字段时先deprecated(reason: ...)再逐步移除v3。配合deprecated与字段描述文档化客户端有充足迁移窗口。五、落地工具一API 设计评审清单api-design-checklist.md 把上述全部规范折叠成一份可勾选的评审清单分为实现前评审与GraphQL 专属检查两大块。实现前评审覆盖 11 个维度资源设计名词化、复数、一致性、层级 ≤2 级、CRUD 映射完整、HTTP 方法语义、状态码10 个关键码、分页全端点覆盖、默认 20 上限 100、元数据、模式选定、过滤/排序/搜索/稀疏字段集、版本化策略、错误处理统一格式、字段级校验、错误码、时间戳、认证授权、限流头部、429、Retry-After、文档OpenAPI、示例、错误文档、测试单测/集成/错误场景/边界/性能、安全输入校验、SQL 注入、XSS、CORS、HTTPS、敏感数据不进 URL、响应无密钥、性能查询优化、防 N1、缓存策略、缓存头、分页大响应、监控日志、错误追踪、指标、健康检查、告警。GraphQL 专属检查聚焦Schema 优先、类型定义、非空决策、接口/联合、自定义标量查询深度限制、复杂度分析、DataLoader 防 N1、分页模式mutation 的 input/payload/乐观响应/幂等性能的批处理、持久化查询、响应缓存以及字段文档、废弃标记、自省开关。这份清单可直接作为团队 PR 评审的硬门槛。六、落地工具二FastAPI 可运行模板剖析rest-api-template.py 是上述规范的可执行化示范采用 FastAPI Pydantic v2可作为新项目骨架。它把规范逐条映射为代码值得逐段对照理解中间件层TrustedHostMiddleware防 HTTP Host 头攻击CORSMiddleware管控跨域——两处均以 TODO 标注生产环境必须收紧allowed_hosts[*]、allow_origins[*]仅为开发便利模型层用Enum限定UserStatusUserBase/UserCreate/UserUpdate分层建模——创建态含passwordmin_length8强校验更新态全字段可选并带范围约束min_length1, max_length100User输出模型含id/created_at/updated_at并开启from_attributesTrue支持 ORM 对象序列化分页契约PaginationParams用Field(1, ge1)与Field(20, ge1, le100)把默认 20、上限 100直接编码进 Pydantic 约束PaginatedResponse固定返回items/total/page/page_size/pages五元组与参考文档的 offset 分页响应完全一致统一错误处理ErrorDetail/ErrorResponse实现code message field 级 details结构全局app.exception_handler(HTTPException)把任意异常归一化为统一 JSON 响应服务端自动兜底错误格式一致性端点语义POST显式status_code201DELETE返回204PATCH用model_dump(exclude_unsetTrue)只更新传入字段天然实现部分更新语义404 通过HTTPException抛出并携带结构化 detail。模板与参考文档的映射关系非常清晰/api/users?pagepage_size对应 3.4 节 offset 分页ErrorResponse对应 3.8 节统一错误结构中间件对应 3.9 节 CORS 与安全规范。开发时只需将 mock 数据源替换为真实存储即可上线。七、局限性与正确使用姿势技能自身的 Limitations 声明见 SKILL.md同样适用于本文内容仅在任务明确匹配上述范围时使用本套方法不要泛化到框架实现或纯基础设施任务设计产出不能替代环境特定验证、测试与专家评审——契约纸面合理不等于实现正确当所需输入需求、权限、安全边界、成功标准缺失时应停下来澄清而不是在模糊前提下强行定稿。实际运用建议新项目按四步工作流走完整流程以清单驱动评审存量 API 重构则先用错误结构、分页元数据、命名一致性等低成本高收益项切入再逐步引入版本化与限流。仓库中该技能同时存在于 plugins/agentic-awesome-skills/skills/api-design-principles 与 plugins/agentic-awesome-skills-claude/skills/api-design-principles 两个插件目录两者内容一致可对照使用后续在 data/aas-v1/skill-content-index.v1.json 中可检索到该技能在目录索引中的注册信息便于理解它在整个技能仓库中的组织方式。赞分享AI 技能AI 插件【免费下载链接】agentic-awesome-skillsAAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validation, and planning, backed by 2,400 agentic skills. Includes CLI, local MCP, catalog, plugins, and Workbench.项目地址https://gitcode.com/gh_mirrors/an/agentic-awesome-skills点击查看免费下载相关推荐agentic-awesome-skills 之 API 设计原则实战手册REST 与 GraphQL 的工程化落地指南agentic awesome skills 之 API 设计原则实战手册REST 与 GraphQL 的工程化落地指南 本指南以 implementatioAI 技能AI 插件GraphQL 设计原则实战指南从选型判断到 Schema 与安全防护agentic-awesome-skills api-patterns 系列GraphQL 设计原则实战指南从选型判断到 Schema 与安全防护agentic awesome skills api patterns 系列 本篇以AI 技能AI 插件基于 agentic-awesome-skills 的 API 设计检查清单REST 与 GraphQL 上线前逐项审查指南基于 agentic awesome skills 的 API 设计检查清单REST 与 GraphQL 上线前逐项审查指南 导读 本文围绕仓库中 api dAI 技能AI 插件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表