REST Design
RESTful API design principles for building consistent, intuitive, and scalable HTTP APIs
You are an expert in RESTful API design for designing robust APIs. ## Key Points - Use query parameters for filtering on resource attributes. - Prefix sort fields with `-` for descending order. - Allow `fields` to limit response payload size. - Use consistent plural nouns for resource names and keep URIs lowercase with hyphens. - Return appropriate HTTP status codes: 201 for creation, 204 for no-content deletes, 409 for conflicts. - Version your API from day one (e.g., `/v1/users`) so you can evolve without breaking clients. - Using verbs in URIs (`/getUser/42`) instead of letting HTTP methods convey the action. - Deeply nesting resources beyond two levels, which creates brittle, hard-to-cache URLs. ## Quick Example ``` GET /users/42/orders # orders belonging to user 42 GET /users/42/orders/7 # order 7 for user 42 ``` ``` GET /users?status=active&sort=-created_at&fields=id,name,email ```
skilldb get api-design-skills/REST DesignFull skill: 133 linesREST Design — API Design
You are an expert in RESTful API design for designing robust APIs.
Core Philosophy
Overview
REST (Representational State Transfer) is an architectural style for networked applications that relies on stateless, resource-oriented interactions over HTTP. Good REST design produces APIs that are predictable, self-descriptive, and easy to consume.
Core Concepts
Resource Naming
Resources are nouns, not verbs. Use plural nouns for collections.
GET /users # list users
POST /users # create a user
GET /users/42 # fetch user 42
PUT /users/42 # replace user 42
PATCH /users/42 # partially update user 42
DELETE /users/42 # delete user 42
Nested Resources
Express relationships through URI hierarchy, but keep nesting shallow (two levels max).
GET /users/42/orders # orders belonging to user 42
GET /users/42/orders/7 # order 7 for user 42
HTTP Methods and Semantics
| Method | Idempotent | Safe | Typical Use |
|---|---|---|---|
| GET | Yes | Yes | Read |
| POST | No | No | Create |
| PUT | Yes | No | Full replace |
| PATCH | No | No | Partial update |
| DELETE | Yes | No | Remove |
Content Negotiation
Use Accept and Content-Type headers to negotiate representation format.
GET /users/42 HTTP/1.1
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": 42,
"name": "Alice",
"email": "alice@example.com"
}
Implementation Patterns
Filtering, Sorting, and Field Selection
GET /users?status=active&sort=-created_at&fields=id,name,email
- Use query parameters for filtering on resource attributes.
- Prefix sort fields with
-for descending order. - Allow
fieldsto limit response payload size.
HATEOAS Links
Include navigational links in responses so clients can discover related actions.
{
"id": 42,
"name": "Alice",
"_links": {
"self": { "href": "/users/42" },
"orders": { "href": "/users/42/orders" }
}
}
Bulk Operations
For endpoints that need to act on multiple resources, use a batch sub-resource.
POST /users/batch
Content-Type: application/json
{
"operations": [
{ "method": "create", "body": { "name": "Bob" } },
{ "method": "delete", "id": 55 }
]
}
Best Practices
- Use consistent plural nouns for resource names and keep URIs lowercase with hyphens.
- Return appropriate HTTP status codes: 201 for creation, 204 for no-content deletes, 409 for conflicts.
- Version your API from day one (e.g.,
/v1/users) so you can evolve without breaking clients.
Common Pitfalls
- Using verbs in URIs (
/getUser/42) instead of letting HTTP methods convey the action. - Deeply nesting resources beyond two levels, which creates brittle, hard-to-cache URLs.
Anti-Patterns
Over-engineering for hypothetical scale. Building for millions of users when you have hundreds adds complexity without value. Solve today's problems first.
Ignoring the existing ecosystem. Reinventing functionality that mature libraries already provide well wastes time and introduces unnecessary risk.
Premature abstraction. Creating elaborate frameworks and utilities before you have enough concrete cases to know what the abstraction should look like produces the wrong abstraction.
Neglecting error handling at boundaries. Internal code can trust its inputs, but system boundaries (user input, APIs, file I/O) require defensive validation.
Skipping documentation for obvious code. What is obvious to you today will not be obvious to your colleague next month or to you next year.
Install this skill directly: skilldb add api-design-skills
Related Skills
API Authentication
API authentication patterns including OAuth 2.0, JWT, and API keys for securing HTTP APIs
API Documentation
OpenAPI and Swagger documentation practices for generating accurate, maintainable API references
API Error Handling
Error response design and HTTP status code conventions for consistent, actionable API error reporting
API Pagination
Pagination patterns including cursor-based, offset, and keyset pagination for efficient list endpoints
API Versioning
API versioning strategies for evolving APIs without breaking existing consumers
GRAPHQL Design
GraphQL schema design patterns for building flexible, efficient, and evolvable query APIs