Communitygithub.com

REST API 设计

设计 REST API 面——资源命名、HTTP 方法与状态码语义、错误格式、分页与过滤,并输出一份消费者无需提问即可直接构建的端点规范。当有人问“这个端点该叫什么”、“该返回什么状态码”、“该用 PUT 还是 PATCH”、“如何分页”或审核即将对外发布的 API 时使用。

REST API 设计 是什么?

此技能专注于为开发者提供一套系统化的 REST API 设计流程,覆盖资源命名、HTTP 方法与状态码语义、错误处理、分页与过滤、性能与负载预算等关键环节。它的核心价值在于预防由于设计不一致(如混合命名、错误的状态码、对增长表使用偏移分页)而导致的、难以修复的消费者适配问题。该技能支持在所有 API 设计场景中使用,但明确建议某些情况(如规划版本弃用、GraphQL 模式设计、生成 SDK)应使用其他专用技能。它提供从输入收集到输出端点规范的完整操作流程,并包含大量正面与反面示例,强调资源优先于方法、一致性高于便利性的设计哲学。最终交付物是一份包含端点路径、方法、状态码、共享错误格式、分页契约、过滤白名单以及性能预算的规范,确保消费者无需额外沟通即可开发客户端。

兼容平台~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/SkillMedev/skills/tree/HEAD/skills/api-design

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

REST API 设计 是做什么的?

API 就是产品:消费者的心智模型决定了 API 的形状,而不是你的数据库 schema。此技能要预防的高代价错误是交付一个不一致的 API 面——混合的命名、错误的状态码、在增长的表上使用偏移分页——这些错误会被每个消费者硬编码适配,一旦集成就几乎无法修复。

操作流程

按此顺序进行。资源优先于方法,因为方法的语义取决于资源是什么;错误和分页契约在编写规范之前确定,因为事后修补会破坏消费者。

步骤 1:收集输入

在设计之前收集信息。任何假设都要标记为猜测。

  1. 消费者:内部服务、第一方客户端或外部开发者。外部消费者会提高一致性标准——如未知则默认按外部处理。
  2. 领域的核心名词以及每个名词的归属关系(驱动嵌套层次)。
  3. 预期的集合大小和增长情况。可能超过 ~10,000 行的列表应排除偏移分页。
  4. 每个端点的读写比例和延迟期望。
  5. 认证模型(影响 401 和 403 的正确性)。

步骤 2:命名资源

  • 复数名词:/users、/orders、/products。
  • 嵌套一层表示归属关系:/users/{id}/orders。不要嵌套超过两层——改用过滤器展平(/orders?user_id=... 优于 /users/{id}/orders/{oid}/items/{iid})。
  • 路径中不要使用动词;HTTP 方法就是动词。对于没有对应 CRUD 动词的真正操作(例如发送发票),可以建模为一个子资源 POST:POST /invoices/{id}/send-attempts。
  • 大小写一致:多词路径段使用 kebab-case,JSON 字段使用 snake_case——选定一种,全局应用。

步骤 3:分配方法和状态码

  • GET:读取,幂等,无请求体。返回 200 并附带体。
  • POST:创建。返回 201,并在 Location 头部指向新资源。在响应体中返回创建的资源表示,这样客户端可以省略后续的 GET 请求。
  • PUT:完全替换,幂等。缺失的字段意味着“清除”,而不是“保留”。
  • PATCH:部分更新(JSON Merge Patch 或 JSON Patch——在规范中说明采用哪一种)。
  • DELETE:删除,幂等,返回 204。删除一个已删除的资源返回 204 或 404——选择其中一种并记录在文档中。
  • 错误:400 表示格式错误的输入,401 表示缺失/无效的凭据,403 表示有效凭单但无权限,404 表示资源不存在(当暴露存在性本身是一种泄露时,也应使用 404 而非 403),409 表示状态冲突,422 表示格式正确但语义无效的输入,429 表示速率限制(附带 Retry-After 头部),500 表示服务器故障——永远不要暴露堆栈跟踪或内部标识符。

步骤 4:确定错误契约

所有错误使用统一格式,机器可读的错误码优先:

{
  "error": "validation_error",
  "message": "Email is required",
  "field": "email",
  "request_id": "req_abc123"
}

request_id 必须在服务端记录,以便支持人员关联问题。Human message 专为开发人员阅读日志而设,永远不要用于最终用户显示。

步骤 5:确定分页和过滤

  • 对任何会增长的集合使用基于游标的分页:返回一个不透明的游标和 has_more 标志。偏移分页仅适用于小范围、有界、面向管理员的列表——它在并发写入下线性退化并导致跳行/重复行。
  • 默认页面大小为 25,最大为 100。超过最大值的页面大小应返回 400 拒绝,不要静默截断。
  • 过滤和排序通过查询参数进行:?status=active&sort=created_at:desc。记录哪些字段可过滤;对未知过滤参数返回 400 拒绝,而不是忽略它们(静默忽略会隐藏客户端错误)。

步骤 6:应用性能和负载预算

  • p95 延迟预算:交互式端点 300 毫秒,报告/导出 1 秒。如果某个操作无法在 1 秒内完成,则将其改为异步:返回 202 Accepted 并附带一个状态资源供轮询。
  • 响应负载预算:保持典型响应在 100 KB 以下;任何经常超过 1 MB 的响应都需要分页、字段选择 (?fields=) 或专门的导出流程。
  • 在 URL 路径中标识版本变更 (/v1/)。新增字段等兼容性变更不需要版本号递增。弃用时间线的处理请交给 api-versioning-strategist。

对比示例

糟糕:

POST /getUserOrders?userId=42&page=3
→ 200 { "data": [...], "error": null }

路径中包含动词,对 POST 使用了 GET 语义,采用了偏移分页,200 响应中包裹了一个 error 字段,导致客户端必须解析响应体才能知道调用是否失败。

良好:

GET /users/42/orders?status=shipped&limit=25&cursor=eyJpZCI6OTh9
→ 200 { "orders": [...], "next_cursor": "eyJpZCI6MTIzfQ", "has_more": true }
→ 404 { "error": "not_found", "message": "User 42 does not exist", "request_id": "req_9f2" }

名词路径,归属嵌套,游标分页,状态码直接表明结果。

交付物

生成一个端点规范,其中包含:资源表格(路径、方法、每个方法涉及的状态码)、共享的错误格式、分页契约(游标格式、默认值、最大值)、过滤白名单,以及每个端点的延迟/负载预算。

禁止事项

  • 不要在 API 中直接映射数据库 schema——消费者会与你想要更改的内部实现耦合。
  • 不要为失败操作返回 200 并附带错误体;客户端和监控工具都依赖状态码。
  • 不要对无界集合使用偏移分页——它会在写入下重复和跳过行,并且线性退化。
  • 不要嵌套路径超过两层;深度嵌套只编码了一种访问路径,排除了所有其他路径。
  • 不要静默忽略未知的查询参数——输入错误的过滤器却返回未过滤的数据是一种数据泄露级别的错误。

质量标准

  • 消费者可以根据 spec 实现客户端,无需提出任何问题。
  • 每个端点都明确其状态码,包括错误情况。
  • 所有集合端点共享一个分页契约;所有错误共享一种格式。
  • 相同概念在每一个路径和负载中都有相同的名称。
  • 每个端点都有明确的延迟预算,超过 1 秒的操作是异步的。

Individual skills in this repo

This repo contains 19 individual skills — each has its own dedicated page.

SkillMedev/skills

Produce an accurate, properly timed caption track (SRT or WebVTT) from a video's audio - transcribing or aligning to the voiceover script, timing cues to speech, and enforcing line-length and reading-speed rules so captions are readable and in sync. Use when someone says "generate captions", "make subtitles from the audio", "transcribe and caption this", "export an SRT or VTT", "the captions are out of sync", or "the subtitles flash by too fast to read". Do NOT use to burn-in, style, reframe, or position an existing caption track for a platform (9:16, brand styling, safe areas) - that is social-video-formatter; do NOT use to animate text word-by-word as a motion graphic - that is kinetic-typography; do NOT use to write the spoken script in the first place - that is narration-script.

SkillMedev/skills

Turns data and charts into a decision-driving narrative structured as headline finding, trend, implication, and recommended action - with finding-led chart titles, context for every number, annotation guidance, and honest flags on any conclusion the data cannot support. Use when someone says "turn these numbers into a story", "what's the takeaway from this data", "help me present these results to leadership", or has charts but no narrative. Do NOT use for compressing a long document into a one-pager - use executive-summary instead - or for running the analysis that produces the findings - use eda-playbook instead.

SkillMedev/skills

Use when a task needs live or historical money data - "convert USD to EUR", "current/past exchange rate", "FX rate on this date / over this range", or "current price of Bitcoin/Ethereum, market cap, 24h change". Frankfurter (ECB reference rates, no key) is the FX default; CoinGecko's free keyless tier covers crypto. Do NOT use for stock quotes or equities - no keyless stock API survives verification, say so instead of guessing; do NOT use for country economic indicators like GDP or inflation series - use government-open-data instead; if the request is a vague "I need live data", route through public-data-api-picker.

SkillMedev/skills

Builds a driver-based FP&A operating model linking business inputs to P&L, balance sheet, and cash flow outputs. Use when building an annual plan, preparing investor materials, running scenario analysis, or stress-testing the business.

SkillMedev/skills

Use when a task needs live geographic lookups - "geocode this address", "what's at these coordinates" (reverse geocoding), "lat/lon for this city", "which country/state is this ZIP or postal code in", or "country facts: capital, currency, population, flag". Nominatim (OpenStreetMap) is the geocoding default; Zippopotam for postal codes; APICountries for country facts. All keyless. Do NOT use for weather at a location - use weather-climate instead; do NOT use for country-level statistics over time (GDP, population trends) - use government-open-data instead; if the request is a vague "I need live data", route through public-data-api-picker.

SkillMedev/skills

Runs the full Getting Things Done loop - capture, clarify, organize, reflect, engage - building a trusted system of context lists, a projects list with defined next actions, and a weekly review habit. Use when someone says "I'm overwhelmed and things are slipping through the cracks", "set up GTD for me", "help me do a brain dump and organize it", or "my to-do list is a mess". Do NOT use for just running the weekly review ritual itself - use weekly-review instead - or for clearing an email backlog - use inbox-zero.

SkillMedev/skills

Processes any email backlog to zero using the 4Ds - Delete, Delegate, Defer, Do - with a mass-archive strategy for the obvious, a touch-each-email-once discipline, and a keep-it-clear system of batched processing windows, ruthless unsubscribing, filters, and a minimal folder setup. Use when someone says "I have 5,000 unread emails", "help me get to inbox zero", "email is eating my whole day", or treats their inbox as a to-do list. Do NOT use for drafting the reply emails themselves or prioritization rules for an ongoing support queue - use email-triage instead - or for protecting focus time around the email windows - use deep-work-planner instead.

SkillMedev/skills

Write landing-page copy section by section - hero, social proof, features-as-benefits, objections, CTA - leading with one promise and proving it down the page. Use when someone asks "write my landing page", "improve my hero headline", "what should the homepage say", "turn these features into benefits", or is shipping a new page for a launch or campaign. Do NOT use for testing and optimizing an existing page's conversion rate - use landing-page-cro instead; for the one-line claim itself use positioning-statement; for the full message ladder use messaging-hierarchy.

SkillMedev/skills

Improves an existing landing page's conversion rate through evidence-first CRO - audit heatmaps and recordings, write structured hypotheses, prioritize with ICE scoring, and run one-variable tests to statistical significance. Use when someone asks "why isn't my landing page converting", "audit this page before we scale spend", "which A/B test should we run first", or after a CVR drop or ahead of a paid-traffic push. Do NOT use for writing a new landing page from scratch - use landing-page-copy instead. Do NOT use for auditing the ad accounts sending the traffic - use paid-acquisition-audit instead. Do NOT use for reading the results of a finished experiment - use ab-test-analyzer instead.

SkillMedev/skills

Runs structured coaching sessions using values clarification and the GROW model, ending every session with one committed action, a deadline, and an if-then plan for the likely obstacle. Use when someone says "I feel stuck in my life", "help me figure out what I want", "hold me accountable to my goals", or "coach me through this decision". Do NOT use for building a stress toolkit - use stress-management instead - or a journaling practice - use journal-framework; for a standing goal-tracking system, use goals-accountability. Coaching, not therapy: signs of clinical distress route to a licensed professional.

SkillMedev/skills

Adapts English content for a target language and region - swapping idioms, setting the right formality register, replacing cultural references, converting dates, units, and currency - and delivers the localized text with a notes column explaining each adaptation and flagging what needs a native reviewer. Use when someone asks "localize this copy for the Japanese market", "adapt our marketing copy for the Mexican market", "make this translation sound native instead of literal", or a literal translation reads foreign, stiff, or risky. Do NOT use for auditing in-product UI text quality - use ux-writing-audit instead.

SkillMedev/skills

Turns a natural-language video brief into a complete, ready-to-preview Remotion composition - extracts duration, scenes, brand colors, aspect ratio, and real copy; plans the frame budget; and writes data-driven React/TypeScript using useCurrentFrame, interpolate, spring, AbsoluteFill, and Sequence, registered in Root.tsx. Use when someone says "build a 20-second product demo video", "animate a feature walkthrough", "write the Remotion code for this marketing clip", or wants a scene-by-scene composition they can scrub in Studio. Do NOT use for rendering, iterating, or batching the finished MP4 - use remotion-render instead - or for installing and scaffolding the project - use remotion-setup instead.

SkillMedev/skills

Scaffolds a new Remotion video project wired for Claude Code Agent Skills - Node check, create-video scaffold, skills install, folder conventions, Google Fonts, and a smoke-test render. Use whenever someone wants to start making videos with Remotion and Claude, even just "make product videos with Claude.

SkillMedev/skills

Classifies incident severity (SEV1-4) using impact, scope, and urgency signals and decides who to page. Use when an alert fires or a report comes in and a severity call must be made quickly.

SkillMedev/skills

Use the Skill Me catalog from inside any conversation - discover, install, and manage Claude skills through the Skill Me MCP, and load installed skills automatically each session.

SkillMedev/skills

Write one platform-native caption from a topic and brand voice, with a front-loaded hook, native length, and a single earned CTA. Use when the user gives a topic (and optionally brand voice or a described image/video) and asks for an Instagram, LinkedIn, X/Twitter, or TikTok caption. Do NOT use when the user wants a dedicated standalone LinkedIn post - use linkedin-post-writer instead; or a multi-post X thread - use tweet-thread-builder instead; or to adapt one existing piece of content into versions for several channels - use cross-platform-reformatter instead.

SkillMedev/skills

Reframe and export a finished video for social platforms - 9:16 ↔ 16:9 cropping, burned-in captions, a platform-native first frame, loop design, and per-platform specs (aspect, length, safe areas) for TikTok, Reels, Shorts, X, and LinkedIn. Use when someone says "make this vertical", "crop to 9:16", "format for TikTok/Reels/Shorts", "add captions/subtitles", "why is my video cut off on mobile", "resize for Instagram", or "export for social". Do NOT use when the question is about the storyboard or shot order before any video exists (use video-storyboard); the animation craft of how elements move (use motion-design-principles); animated word-by-word caption styling (use kinetic-typography); palette, contrast, or lighting (use motion-color-and-light); directing the product-demo content and screen choreography (use product-demo-director); or scoring, beat-syncing, or audio (use sound-and-music-sync) - this is the craft layer that decides WHAT to format for the feed, then hands a concrete spec to remotion-compo...

SkillMedev/skills

Writes and tunes PySpark jobs - join strategy and broadcast size limits, shuffle-partition sizing, skew diagnosis and salting, UDF avoidance, caching, and output file layout - with concrete size and skew thresholds. Use when someone asks "why is my Spark job slow", "should I broadcast this join", "one task takes forever while the rest finish", "my job OOMs during a join", or is writing a new PySpark ETL job. Do NOT use for Kafka topic, consumer-group, or streaming-pipeline design - use kafka-pipelines instead; do NOT use for single-machine dataframe work that fits in memory - use pandas-expert instead.

SkillMedev/skills

Builds clean, performant, accessible SwiftUI views with correct state ownership, scoped invalidation, and smooth list scrolling, and reviews existing SwiftUI code against a concrete frame-time and re-render budget. Use when someone asks "why does my SwiftUI list stutter", "should this be @State or @Observable", "my whole screen re-renders when one row changes", "how do I animate this transition", or wants a SwiftUI view built or refactored. Do NOT use for cross-platform React Native apps - use react-native-pro instead; do NOT use for Flutter widget trees - use flutter-widget-architect instead; do NOT use for Android Compose UIs - use jetpack-compose-builder instead.

相关技能