Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问许可证需确认审计通过

api-design-patternsAPI 设计模式

Agent Skill

用于辅助 API 设计、接口文档、请求响应结构和服务集成说明。它适合让 Agent 梳理 endpoint、生成 OpenAPI 草稿、检查字段命名、整理错误码或辅助前后端联调。使用时需要确认真实业务语义、鉴权方式、分页和错误处理规则;涉及生成接口文档时,应避免凭空补字段,最好从现有代码、schema 或接口样例中提取事实。

总安装

753

周安装

32

GitHub Stars

8

下载量

264
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:api-design-patterns(API 设计模式)
来源仓库:https://github.com/hieutrtr/ai1-skills
仓库路径:skills/api-design-patterns
安装命令:
npx skills add https://github.com/hieutrtr/ai1-skills --skill api-design-patterns
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/hieutrtr/ai1-skills --skill api-design-patterns

简介

api-design-patterns 用于辅助 API 设计、接口文档和请求响应结构说明。

  • 适合让 Agent 梳理 endpoint、生成 OpenAPI 草稿或检查字段命名,需确认真实业务语义和鉴权方式。
  • 涉及生成接口文档时,应避免凭空补字段,最好从现有代码或接口样例中提取事实。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装,需确认权限和维护状态。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

API Design Patterns

When to Use

Activate this skill when:

  • Designing new API endpoints or modifying existing endpoint contracts
  • Defining request/response schemas for a feature
  • Standardizing pagination, filtering, or sorting across endpoints
  • Designing a consistent error response format
  • Planning API versioning or deprecation strategy
  • Reviewing API contracts for consistency before implementation
  • Documenting endpoint specifications for frontend/backend coordination

Input: If plan.md or architecture.md exists, read for context about the feature scope and architectural decisions. Otherwise, work from the user's request directly.

Output: Write API design to api-design.md. Tell the user: "API design written to api-design.md. Run /task-decomposition to create implementation tasks or /python-backend-expert to implement."

Do NOT use this skill for:

  • Writing implementation code (use python-backend-expert)
  • System-level architecture decisions (use system-architecture)
  • Writing tests for endpoints (use pytest-patterns)
  • Frontend data fetching implementation (use react-frontend-expert)

Instructions

URL Naming Conventions

Resource Naming Rules

  1. Plural nouns for collections: /users, /orders, /products
  2. Kebab-case for multi-word resources: /order-items, /user-profiles
  3. Singular resource by ID: /users/{user_id}, /orders/{order_id}
  4. Maximum 2 nesting levels: /users/{user_id}/orders (not /users/{user_id}/orders/{order_id}/items/{item_id})
  5. No verbs in URLs: use HTTP methods instead (POST /orders not /orders/create)
  6. Query parameters for filtering, sorting, pagination: /users?role=admin&sort=-created_at

URL Structure Template

/{version}/{resource}                    → Collection (list, create)
/{version}/{resource}/{id}               → Single resource (get, update, delete)
/{version}/{resource}/{id}/{sub-resource} → Nested collection
/{version}/{resource}/actions/{action}   → Non-CRUD operations (rarely needed)

Naming Examples

GoodBadReason
GET /v1/usersGET /v1/getUsersNo verbs — HTTP method implies action
POST /v1/usersPOST /v1/user/createPOST to collection = create
GET /v1/order-itemsGET /v1/orderItemsKebab-case, not camelCase
GET /v1/users/{id}/ordersGET /v1/users/{id}/orders/{oid}/itemsMax 2 nesting levels
POST /v1/orders/{id}/actions/cancelPOST /v1/cancelOrder/{id}Action sub-resource for non-CRUD

HTTP Method Semantics

MethodPurposeRequest BodySuccess StatusIdempotent
GETRetrieve resource(s)None200 OKYes
POSTCreate new resourceRequired201 CreatedNo
PUTFull replaceRequired (full)200 OKYes
PATCHPartial updateRequired (partial)200 OKNo*
DELETERemove resourceNone204 No ContentYes

*PATCH is not inherently idempotent but can be made so with proper implementation.

Response headers for creation:

  • POST returning 201 SHOULD include a Location header with the URL of the created resource

Conditional requests:

  • Support If-None-Match / ETag for caching on GET endpoints with frequently-accessed resources

Schema Naming Conventions (Pydantic v2)

Follow a consistent naming pattern for all Pydantic schemas:

PatternPurposeFields
{Resource}CreatePOST request bodyWritable fields, no id, no timestamps
{Resource}UpdatePUT request bodyAll writable fields required
{Resource}PatchPATCH request bodyAll fields Optional
{Resource}ResponseSingle resource responseAll fields including id, timestamps
{Resource}ListResponsePaginated list responseitems + pagination metadata
{Resource}FilterQuery parametersOptional filter fields

Schema design rules:

  • Never expose internal fields (hashed_password, internal_notes) in Response schemas
  • Always include id and timestamps (created_at, updated_at) in Response schemas
  • Use model_validate(orm_instance) to convert ORM models to response schemas
  • Use model_dump(exclude_unset=True) for PATCH operations to distinguish "not provided" from "set to null"
  • Reference references/pydantic-schema-examples.md for concrete examples

Pagination

Cursor-Based Pagination (Default)

Use cursor-based pagination for all list endpoints. It is more performant than offset-based for large datasets and avoids the "shifting window" problem.

Request parameters:

GET /v1/users?cursor=eyJpZCI6MTAwfQ&limit=20
ParameterTypeDefaultDescription
cursor`str \None`NoneOpaque cursor from previous response
limitint20Items per page (max 100)

Response format:

{
  "items": [...],
  "next_cursor": "eyJpZCI6MTIwfQ",
  "has_more": true
}

Cursor implementation:

  • Encode the last item's sort key (usually id) as a base64 string
  • The cursor is opaque to the client — they must not parse or construct it
  • Use WHERE id >:last_id ORDER BY id ASC LIMIT:limit + 1 — fetch one extra to determine has_more

Offset-Based Pagination (When Needed)

Use offset-based only when the client needs to jump to arbitrary pages (e.g., admin tables).

{
  "items": [...],
  "total": 150,
  "page": 2,
  "page_size": 20,
  "total_pages": 8
}

Filtering and Sorting

Filtering

Use query parameters with field names:

GET /v1/users?role=admin&is_active=true&created_after=2024-01-01

Filtering conventions:

  • Exact match: ?field=value
  • Range: ?field_min=10&field_max=100 or ?created_after=...&created_before=...
  • Search: ?q=search+term (for full-text search across multiple fields)
  • Multiple values: ?status=active&status=pending (OR semantics)

Sorting

Use a sort query parameter with field name and direction prefix:

GET /v1/users?sort=-created_at        → descending by created_at
GET /v1/users?sort=name               → ascending by name
GET /v1/users?sort=-created_at,name   → multi-field sort

Convention: - prefix means descending, no prefix means ascending.

Error Response Format

All API errors follow a consistent format:

{
  "detail": "Human-readable error message",
  "code": "MACHINE_READABLE_CODE",
  "field_errors": [
    {
      "field": "email",
      "message": "Invalid email format",
      "code": "INVALID_FORMAT"
    }
  ]
}

Standard Error Codes and Status Mapping

HTTP StatusWhen to UseExample code
400Malformed requestBAD_REQUEST
401Missing or invalid authenticationUNAUTHORIZED
403Authenticated but not authorizedFORBIDDEN
404Resource not foundNOT_FOUND
409Conflict (duplicate, version mismatch)CONFLICT
422Validation error (Pydantic)VALIDATION_ERROR
429Rate limit exceededRATE_LIMITED
500Unexpected server errorINTERNAL_ERROR

Error schema (Pydantic v2):

class FieldError(BaseModel):
    field: str
    message: str
    code: str

class ErrorResponse(BaseModel):
    detail: str
    code: str
    field_errors: list[FieldError] = []

API Versioning

Strategy: URL Prefix Versioning

/v1/users    → Version 1
/v2/users    → Version 2

Versioning rules:

  1. Start with /v1/ for all new APIs
  2. Increment major version only for breaking changes
  3. Non-breaking changes (new optional fields, new endpoints) do NOT require a new version
  4. Support at most 2 active versions simultaneously

Breaking changes that require a new version:

  • Removing a field from a response
  • Changing a field's type
  • Making an optional request field required
  • Changing the URL structure for existing endpoints
  • Changing error response format

Deprecation process:

  1. Add Deprecation header to the old version: Deprecation: true
  2. Add Sunset header with the retirement date: Sunset: Sat, 01 Mar 2026 00:00:00 GMT
  3. Add Link header pointing to the new version: Link: </v2/users>; rel="successor-version"
  4. Log usage of deprecated endpoints for monitoring
  5. Remove the old version after the sunset date

OpenAPI Documentation

FastAPI generates OpenAPI schemas automatically. Enhance them with:

@router.get(
    "/users/{user_id}",
    response_model=UserResponse,
    summary="Get user by ID",
    description="Retrieve a single user's details by their unique identifier.",
    responses={
        404: {"model": ErrorResponse, "description": "User not found"},
    },
    tags=["Users"],
)
async def get_user(user_id: int) -> UserResponse:
    ...

Documentation conventions:

  • Every endpoint has a summary (short) and optional description (detailed)
  • Document all non-200 responses with their schema
  • Group endpoints by tags matching the resource name
  • Use response_model for automatic response schema documentation

Examples

Designing a Products API Contract

Objective: Design the contract for a /v1/products CRUD endpoint with search and pagination.

Endpoints:

MethodPathDescriptionRequestResponseStatus
GET/v1/productsList productsQuery: cursor, limit, q, category, sortProductListResponse200
POST/v1/productsCreate productBody: ProductCreateProductResponse201
GET/v1/products/{id}Get productProductResponse200
PATCH/v1/products/{id}Update productBody: ProductPatchProductResponse200
DELETE/v1/products/{id}Delete product204

Schemas:

class ProductCreate(BaseModel):
    name: str = Field(min_length=1, max_length=200)
    description: str | None = None
    price_cents: int = Field(gt=0)
    category: str
    sku: str = Field(pattern=r"^[A-Z0-9-]+$")

class ProductPatch(BaseModel):
    name: str | None = None
    description: str | None = None
    price_cents: int | None = Field(default=None, gt=0)
    category: str | None = None

class ProductResponse(BaseModel):
    id: int
    name: str
    description: str | None
    price_cents: int
    category: str
    sku: str
    created_at: datetime
    updated_at: datetime

class ProductListResponse(BaseModel):
    items: list[ProductResponse]
    next_cursor: str | None
    has_more: bool

Search and filtering:

GET /v1/products?q=laptop&category=electronics&sort=-price_cents&limit=20

See references/endpoint-catalog-template.md for the full documentation template. See references/pydantic-schema-examples.md for additional schema examples.

Edge Cases

Bulk Operations

For operations on multiple resources at once:

POST /v1/users/bulk

Request:

{
  "items": [
    {"email": "a@example.com", "name": "Alice"},
    {"email": "b@example.com", "name": "Bob"}
  ]
}

Response (partial success — status 207):

{
  "results": [
    {"index": 0, "status": "created", "data": {...}},
    {"index": 1, "status": "error", "error": {"detail": "Email already exists", "code": "CONFLICT"}}
  ],
  "succeeded": 1,
  "failed": 1
}

Use HTTP 207 Multi-Status when individual items can succeed or fail independently.

File Upload Endpoints

File uploads use multipart/form-data, not JSON:

@router.post("/v1/files", response_model=FileResponse, status_code=201)
async def upload_file(
    file: UploadFile,
    description: str = Form(default=""),
) -> FileResponse:
    ...

Validate file size and MIME type before processing. Return 413 Payload Too Large for oversized files.

Long-Running Operations

For operations that cannot complete within a normal request timeout:

  1. Return 202 Accepted with a status URL: {"status_url": "/v1/jobs/abc123", "estimated_completion": "2024-01-15T10:30:00Z"}
  2. Client polls the status URL: GET /v1/jobs/abc123 → {"status": "processing", "progress": 0.65} GET /v1/jobs/abc123 → {"status": "completed", "result_url": "/v1/reports/xyz"}

Sub-Resource Design

When a resource logically belongs to a parent but nesting would exceed 2 levels, use a top-level resource with a filter:

# Instead of: GET /v1/users/{id}/orders/{oid}/items
# Use:        GET /v1/order-items?order_id=123

This keeps URLs flat while maintaining the relationship through filtering.

Output File

Write the API design to api-design.md at the project root:

# API Design: [Feature Name]

## Endpoints

| Method | URL | Description | Auth |
|--------|-----|-------------|------|
| GET | /v1/users | List users | Required |
| POST | /v1/users | Create user | Required |

## Request/Response Schemas

### UserCreate
| Field | Type | Required | Validation |
|-------|------|----------|------------|
| email | string | Yes | Valid email |
| name | string | Yes | 1-100 chars |

### UserResponse
| Field | Type | Description |
|-------|------|-------------|
| id | uuid | User ID |
| email | string | User email |

## Error Codes

| Code | HTTP Status | Description |
|------|-------------|-------------|
| USER_NOT_FOUND | 404 | User does not exist |
| EMAIL_EXISTS | 409 | Email already registered |

## Next Steps
- Run `/task-decomposition` to create implementation tasks
- Run `/python-backend-expert` to implement endpoints

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

40.84%
按下载量换算108

Claude

29.42%
按下载量换算78

Cursor

18.05%
按下载量换算48

Gemini CLI

9.46%
按下载量换算25

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills