Skip to main content
ClaudeWave
Skill1.1k estrellas del repoactualizado today

moai-ref-api-patterns

This Claude Code skill provides standardized RESTful API design conventions and implementation patterns for backend development. It includes specifications for resource naming, HTTP methods, status codes, error response formatting, and pagination structures. Use this reference when designing new APIs, reviewing API implementations, or ensuring consistency across the expert-backend agent's API development work.

Instalar en Claude Code
Copiar
git clone --depth 1 https://github.com/modu-ai/moai-adk /tmp/moai-ref-api-patterns && cp -r /tmp/moai-ref-api-patterns/.claude/skills/moai-ref-api-patterns ~/.claude/skills/moai-ref-api-patterns
Después abre una sesión nueva de Claude Code; el skill carga automáticamente.

skill.md

# API Patterns Reference

## Target Agent

`expert-backend` - 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

```json
{
  "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

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

For cursor-based (large datasets):
```json
{
  "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 wi