Agent Skills: API Patterns Reference

>

domainID: modu-ai/moai-adk/moai-ref-api-patterns

Repository

modu-aiLicense: Apache-2.0
1,211223

Install this agent skill to your local

pnpm dlx add-skill https://github.com/modu-ai/moai-adk/tree/HEAD/.claude/skills/moai-ref-api-patterns

Skill Files

Browse the full folder contents for moai-ref-api-patterns.

Download Skill

Loading file tree…

.claude/skills/moai-ref-api-patterns/SKILL.md

Skill Metadata

Name
moai-ref-api-patterns
Description
>

API Patterns Reference

Target Spawn

Backend domain work spawned via Agent(general-purpose) with backend instructions - Applies these patterns directly to API implementation and review.

RESTful API Design Conventions

| Principle | Convention | Example | |-----------|-----------|---------| | Resource Naming | Plural nouns, lowercase, kebab-case | /api/v1/user-profiles | | Collection | GET returns array with pagination | GET /users?page=1&limit=20 | | Single Resource | GET returns object | GET /users/{id} | | Create | POST to collection | POST /users | | Update (full) | PUT to resource | PUT /users/{id} | | Update (partial) | PATCH to resource | PATCH /users/{id} | | Delete | DELETE to resource | DELETE /users/{id} | | Nested Resources | Max 2 levels deep | /users/{id}/posts | | Filtering | Query params | ?status=active&role=admin | | Sorting | Sort param | ?sort=-created_at,name | | Versioning | URL prefix | /api/v1/, /api/v2/ |

HTTP Status Code Guide

| Category | Code | When to Use | |----------|------|-------------| | Success | 200 OK | Successful GET, PUT, PATCH, DELETE | | Success | 201 Created | Successful POST (resource created) | | Success | 204 No Content | Successful DELETE (no body) | | Client Error | 400 Bad Request | Malformed request, validation failure | | Client Error | 401 Unauthorized | Missing or invalid authentication | | Client Error | 403 Forbidden | Authenticated but not authorized | | Client Error | 404 Not Found | Resource does not exist | | Client Error | 409 Conflict | Resource state conflict (duplicate) | | Client Error | 422 Unprocessable | Valid syntax but semantic error | | Client Error | 429 Too Many | Rate limit exceeded | | Server Error | 500 Internal | Unexpected server error | | Server Error | 503 Service Unavailable | Maintenance or overload |

Error Response Format

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Input validation failed",
    "details": [
      {"field": "email", "message": "Must be a valid email address"},
      {"field": "age", "message": "Must be between 0 and 150"}
    ],
    "request_id": "req_abc123"
  }
}

Rules:

  • Never expose stack traces or internal details in production
  • Always include request_id for traceability
  • Use consistent error codes (ENUM, not free text)
  • Login failures: "Invalid email or password" (never reveal which)

Pagination Pattern

{
  "data": [...],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 150,
    "total_pages": 8,
    "has_next": true,
    "has_prev": false
  }
}

For cursor-based (large datasets):

{
  "data": [...],
  "cursor": {
    "next": "eyJpZCI6MTAwfQ==",
    "has_more": true
  }
}

Input Validation Checklist

| Validation | Method | Tool | |-----------|--------|------| | Type validation | Schema validation | Zod, Joi, pydantic, Go validator | | Length limits | Min/max constraints | Schema min/max | | Pattern matching | Regex | Email, URL, phone patterns | | Range validation | Number/date bounds | min/max values | | Enumeration | Allowed values | enum types | | SQL Injection | Parameterized queries | ORM (Prisma, GORM, SQLAlchemy) | | XSS | HTML escaping | Template engines, DOMPurify | | Path Traversal | Path normalization | filepath.Clean + whitelist |

Rate Limiting Strategy

| Target | Limit | Key | |--------|-------|-----| | Auth endpoints | 5 req/min | IP | | General API | 100 req/min | User token | | File upload | 10 req/hour | User token | | Public API | 30 req/min | IP |

Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After (on 429).

API Versioning Strategy

| Strategy | Use Case | Example | |----------|----------|---------| | URL prefix | Most APIs | /api/v1/users | | Header | Internal APIs | Accept: application/vnd.api+json; version=2 | | Query param | Simple APIs | /users?version=2 |

Breaking changes that require version bump:

  • Removing or renaming fields
  • Changing field types
  • Removing endpoints
  • Changing authentication methods

Non-breaking changes (no version bump needed):

  • Adding new optional fields
  • Adding new endpoints
  • Adding new query parameters
<!-- moai:evolvable-start id="rationalizations" -->

Common Rationalizations

| Rationalization | Reality | |---|---| | "REST naming conventions are just aesthetics" | Consistent resource naming is how clients discover and predict endpoints. Inconsistency multiplies documentation burden. | | "GraphQL solves over-fetching, so I do not need to design response shapes" | GraphQL shifts complexity to the resolver layer. Poorly designed schemas create N+1 queries and authorization gaps. | | "Error codes are internal details, clients just need the message" | Clients need machine-readable error codes for programmatic handling. Messages are for humans, codes are for code. | | "PATCH and PUT are interchangeable" | PATCH applies partial updates; PUT replaces the entire resource. Using them incorrectly breaks idempotency expectations. | | "I will version the API when it becomes necessary" | Versioning after breaking changes forces emergency migrations. Plan versioning from the first release. |

Hyrum's Law: Every observable API behavior will eventually be depended on by clients. Undocumented response fields, error formats, and timing characteristics become implicit contracts.

<!-- moai:evolvable-end --> <!-- moai:evolvable-start id="red-flags" -->

Red Flags

  • API returns different error formats across endpoints
  • Resource names use verbs instead of nouns (e.g., /getUser instead of /users/:id)
  • No pagination on list endpoints that can return unbounded results
  • Breaking change deployed without API version bump
  • GraphQL schema allows unbounded depth or circular queries without limits
<!-- moai:evolvable-end --> <!-- moai:evolvable-start id="verification" -->

Verification

  • [ ] All endpoints follow consistent naming convention (nouns, plurals, nested resources)
  • [ ] Error responses use a standard format with machine-readable error code
  • [ ] List endpoints implement pagination with documented limits
  • [ ] API versioning strategy present and enforced (URL path, header, or query param)
  • [ ] Breaking vs non-breaking change classification documented for recent changes
  • [ ] Input validation returns 400 with specific field-level error details
<!-- moai:evolvable-end -->