REST API design best practices for consistent, intuitive APIs
/plugin marketplace add Benny9193/devflow/plugin install benny9193-devflow@Benny9193/devflowThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Design APIs that are intuitive, consistent, and a joy to use.
# GOOD - nouns
GET /users
GET /users/123
GET /users/123/orders
# BAD - verbs
GET /getUsers
GET /fetchUserById/123
POST /createNewUser
# GOOD - plural
GET /users
GET /orders
GET /products
# BAD - singular
GET /user
GET /order
# Parent-child relationships
GET /users/123/orders # Orders for user 123
GET /orders/456/items # Items in order 456
# Avoid deep nesting (max 2 levels)
# BAD
GET /users/123/orders/456/items/789/reviews
# GOOD - flatten when needed
GET /order-items/789/reviews
| Method | Usage | Idempotent | Safe |
|---|---|---|---|
| GET | Read resource | Yes | Yes |
| POST | Create resource | No | No |
| PUT | Replace resource | Yes | No |
| PATCH | Partial update | Yes | No |
| DELETE | Remove resource | Yes | No |
GET /users # List users
POST /users # Create user
GET /users/123 # Get user 123
PUT /users/123 # Replace user 123
PATCH /users/123 # Update user 123
DELETE /users/123 # Delete user 123
// Success response
{
"data": {
"id": "123",
"name": "John Doe",
"email": "john@example.com"
}
}
// Collection response
{
"data": [
{ "id": "123", "name": "John" },
{ "id": "456", "name": "Jane" }
],
"meta": {
"total": 100,
"page": 1,
"perPage": 20
}
}
// Error response
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid email format",
"details": [
{ "field": "email", "message": "Must be a valid email" }
]
}
}
// GOOD
{
"firstName": "John",
"lastName": "Doe",
"emailAddress": "john@example.com"
}
// BAD - inconsistent
{
"first_name": "John",
"LastName": "Doe",
"email-address": "john@example.com"
}
200 OK - GET, PUT, PATCH success
201 Created - POST success (include Location header)
204 No Content - DELETE success
400 Bad Request - Invalid syntax, validation error
401 Unauthorized - No/invalid authentication
403 Forbidden - Authenticated but not allowed
404 Not Found - Resource doesn't exist
409 Conflict - State conflict (duplicate, version)
422 Unprocessable - Valid syntax but semantic error
429 Too Many Requests - Rate limited
500 Internal Server Error - Unexpected error
502 Bad Gateway - Upstream service failed
503 Service Unavailable - Temporarily unavailable
504 Gateway Timeout - Upstream timeout
GET /users?page=2&perPage=20
Response:
{
"data": [...],
"meta": {
"total": 100,
"page": 2,
"perPage": 20,
"totalPages": 5
},
"links": {
"first": "/users?page=1&perPage=20",
"prev": "/users?page=1&perPage=20",
"next": "/users?page=3&perPage=20",
"last": "/users?page=5&perPage=20"
}
}
GET /users?cursor=eyJpZCI6MTIzfQ&limit=20
Response:
{
"data": [...],
"meta": {
"hasMore": true,
"nextCursor": "eyJpZCI6MTQzfQ"
}
}
GET /users?status=active
GET /users?role=admin&status=active
GET /users?createdAt[gte]=2024-01-01
GET /users?name[contains]=john
GET /users?sort=name # Ascending
GET /users?sort=-createdAt # Descending (prefix -)
GET /users?sort=lastName,firstName
GET /users?fields=id,name,email
GET /users/123?fields=id,name,email
GET /v1/users
GET /v2/users
GET /users
Accept: application/vnd.api+json;version=2
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
X-API-Key: sk_live_abc123
# Or in query (less secure)
GET /users?api_key=sk_live_abc123
Include headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
Retry-After: 60
Every endpoint needs:
# OpenAPI example
/users:
post:
summary: Create a new user
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateUser'
responses:
'201':
description: User created
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'400':
description: Validation error
| Mistake | Problem | Fix |
|---|---|---|
| Verbs in URLs | /getUser | Use /users/:id |
| Inconsistent naming | Mix of cases | Pick one (camelCase) |
| Wrong status codes | 200 for errors | Use 4xx/5xx appropriately |
| No pagination | Memory issues | Always paginate collections |
| Breaking changes | Clients break | Version your API |
| No rate limiting | Abuse | Implement limits |
| Exposing internals | Security risk | Transform responses |
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.