Awesome-claude-code-toolkit api-design-patterns

REST API design with resource naming, pagination, versioning, and OpenAPI spec generation

install
source · Clone the upstream repo
git clone https://github.com/rohitg00/awesome-claude-code-toolkit
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/rohitg00/awesome-claude-code-toolkit "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/api-design-patterns" ~/.claude/skills/rohitg00-awesome-claude-code-toolkit-api-design-patterns && rm -rf "$T"
manifest: skills/api-design-patterns/SKILL.md
source content

API Design Patterns

Resource Naming

  • Use plural nouns:
    /users
    ,
    /orders
    ,
    /products
  • Nest for relationships:
    /users/{id}/orders
  • Max nesting depth: 2 levels. Beyond that, use query params or top-level resources
  • Use kebab-case:
    /user-profiles
    , not
    /userProfiles
  • Never put verbs in URLs:
    /users/{id}/activate
    is wrong, use
    POST /users/{id}/activation

HTTP Methods

MethodPurposeIdempotentRequest BodySuccess Code
GETRead resource(s)YesNo200
POSTCreate resourceNoYes201
PUTFull replaceYesYes200
PATCHPartial updateNoYes200
DELETERemove resourceYesNo204

Return

Location
header on POST with the URL of the created resource.

Status Codes

200 OK              - Successful read/update
201 Created         - Successful creation
204 No Content      - Successful delete
400 Bad Request     - Validation error (include field-level errors)
401 Unauthorized    - Missing or invalid authentication
403 Forbidden       - Authenticated but not authorized
404 Not Found       - Resource does not exist
409 Conflict        - State conflict (duplicate, version mismatch)
422 Unprocessable   - Semantically invalid (valid JSON, bad values)
429 Too Many Reqs   - Rate limited (include Retry-After header)
500 Internal Error  - Unhandled server error (never expose stack traces)

Error Response Format

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      { "field": "email", "message": "Must be a valid email address" },
      { "field": "age", "message": "Must be at least 18" }
    ]
  }
}

Use consistent error codes across the API. Document every code in your API reference.

Cursor-Based Pagination (preferred)

GET /users?limit=20&cursor=eyJpZCI6MTAwfQ

Response:
{
  "data": [...],
  "pagination": {
    "next_cursor": "eyJpZCI6MTIwfQ",
    "has_more": true
  }
}

Use cursor pagination for large or frequently changing datasets. Encode cursors as opaque base64 strings. Never expose raw IDs in cursors.

Offset-Based Pagination (simple cases only)

GET /users?page=3&per_page=20

Response:
{
  "data": [...],
  "pagination": {
    "page": 3,
    "per_page": 20,
    "total": 245,
    "total_pages": 13
  }
}

Only use offset pagination when total count is cheap and dataset is small.

Filtering and Sorting

GET /orders?status=pending&created_after=2025-01-01&sort=-created_at,+total
GET /products?category=electronics&price_min=100&price_max=500
GET /users?search=john&fields=id,name,email

Use field selection (

fields
param) to reduce payload size. Prefix sort fields with
-
for descending.

Versioning

Prefer URL path versioning for simplicity:

/api/v1/users
/api/v2/users

Rules:

  • Never break v1 once published. Add fields, never remove them.
  • New required fields = new version
  • Deprecate old versions with
    Sunset
    header and 6-month notice
  • Support at most 2 active versions simultaneously

Request/Response Headers

Content-Type: application/json
Accept: application/json
Authorization: Bearer <token>
X-Request-Id: <uuid>          # For tracing
X-RateLimit-Limit: 100        # Requests per window
X-RateLimit-Remaining: 47     # Remaining in window
X-RateLimit-Reset: 1700000000 # Window reset Unix timestamp
Retry-After: 30               # Seconds until rate limit resets

Always return

X-Request-Id
in responses for debugging.

OpenAPI Spec Guidelines

  • Write spec first, then implement (spec-driven development)
  • Use
    $ref
    for shared schemas:
    $ref: '#/components/schemas/User'
  • Define
    examples
    for every endpoint
  • Use
    oneOf
    /
    anyOf
    for polymorphic responses
  • Generate client SDKs from the spec, never hand-write them
  • Validate requests against the spec in middleware
paths:
  /users/{id}:
    get:
      operationId: getUser
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: User found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          $ref: '#/components/responses/NotFound'

Rate Limiting Strategy

  • Apply per-user, per-endpoint limits
  • Use sliding window algorithm (not fixed window)
  • Return
    429
    with
    Retry-After
    header
  • Exempt health check and auth endpoints from rate limits
  • Log rate-limited requests for abuse detection