REST API Design Guidelines
REST API Design Guidelines¶
1. Purpose¶
1.1. The purpose of this document is to establish clear and consistent guidelines for designing REST API URLs. By adhering to widely accepted conventions, development teams can ensure that APIs are intuitive, maintainable, and aligned with industry best practices. This helps improve developer experience, facilitates easier integration, and promotes scalable architecture across services. These conventions are especially relevant for teams working with platforms like Azure API Management, where clarity and consistency in endpoint design are critical for effective API governance and lifecycle management.
2. CORE Principles¶
2.1. Resource oriented design (nouns, not verbs). URLs identify resources; HTTP methods perform actions on those resources. Example: GET /users/42, not GET /getUser?id=42.
2.2. Stable, predictable URLs are a contract. Once published, path shapes should be considered breaking if changed; design carefully up front.
2.3. Consistency over cleverness. Use a single, consistent scheme for pluralization, casing, and hierarchy across all services.
2.4. Security-by-design in URLs. Minimize information disclosure in paths; avoid exposing PII, secrets, or internal structure; treat URLs as part of your attack surface.
3. URL Structure¶
3.1. General template:
3.1.1. https://api.example.com/v{major}/{collection}/{id}/{sub-collection}/{sub-id}
3.2. HTTPS only and an API host (e.g., api.example.com). Keep the path semantic and short.
3.3. Version in the path (major only): /v1/.... New major versions create new base paths; minor/patch changes must be non-breaking.
3.4. Plural nouns for collections; singular IDs for items: /users → /users/{userId}.
3.5. Hierarchies with / to reflect relationships: /customers/{customerId}/accounts/{accountId}.
3.6. No trailing slash: /users/42 over /users/42/.
3.7. Lowercase + hyphens in path segments (kebab-case): /shipping-addresses, not /shippingAddresses or /Shipping_Addresses.
3.8. Do not use verbs in paths (use HTTP methods): /orders + POST (create), not /createOrder.
3.9. Examples:
GET /v1/users
GET /v1/users/42
GET /v1/users/42/orders?status=open&sort=-createdAt&page=2&limit=50
POST /v1/orders
PATCH /v1/orders/789
4. Modeling Resources & Identifiers¶
4.1. Prefer opaque server-generated IDs in paths (UUIDs, snowflakes); don’t leak PII or sensitive business context (e.g., account numbers) in URLs.
4.2. Use descriptive parameter names in templates (e.g., {customerId}, {orderId}) to improve readability and docs.
4.3. Keep paths human‑readable, but avoid revealing internal implementation details or workflow steps.
5. Query Parameters: Filtering, Sorting, Pagination¶
5.1. Use query parameters to refine collection results; do not create new endpoints for common filters.
5.2. Filtering: /products?category=electronics&brand=apple.
5.3. Sorting: /products?sort=price_asc (or sort=-price for descending—pick one style and standardize).
5.4. Pagination: /products?page=2&limit=20 (or offset/limit if needed). Document defaults and maximums.
5.5. When to Use POST Instead of GET for Complex Queries
5.5.1 Normally, GET with query parameters is the standard for filtering, sorting, and pagination because it is idempotent, safe, and cacheable. However, there are valid cases where POST is acceptable or recommended:
5.5.1.1. Complex Query Payloads: If the filter criteria are too complex or deeply nested to fit cleanly in a query string (e.g., multiple AND/OR conditions, ranges, arrays of objects). Example:
POST /v1/products/search
Content-Type: application/json
{
"category": "electronics",
"brands": ["apple", "samsung"],
"priceRange": { "min": 500, "max": 1500 },
"sort": [{ "field": "price", "direction": "desc" }],
"pagination": { "page": 2, "limit": 50 }
}
5.5.1.2. Payload Size Limitations: URLs have practical length limits (often ~2,000 characters in browsers). If your query exceeds that, POST with a JSON body is safer.
5.5.1.3. Sensitive Data: If filters include sensitive information (e.g., personally identifiable info, tokens), avoid putting them in the URL because URLs can appear in logs, browser history, and analytics tools.
5.5.1.4. Advanced Search Features: When supporting full-text search, fuzzy matching, or custom scoring that requires structured input beyond simple key-value pairs.
5.5.1.5. Consistency with Existing API Design: If your API already uses /search endpoints for complex queries, POST aligns with that pattern.
5.5.1.6. Rule of Thumb: Simple, predictable filters → GET with query params. Complex, large, or sensitive filters → POST with JSON body.
6. Payload¶
6.1. Use camelCase for JSON property names.
Adopt camelCase (e.g., firstName, orderStatus) for all JSON keys in request and response payloads. This aligns with common conventions in JavaScript, TypeScript, and many frontend frameworks, improving consistency across client-server interactions.
6.2. Do not use snake_case or PascalCase in JSON.
While some languages (e.g., Python) prefer snake_case and Go uses PascalCase for struct fields, JSON payloads should consistently use camelCase. Backend services should map internal naming conventions to camelCase via serialization/deserialization mechanisms (e.g., struct tags in Go, field aliases in Python).
6.3. Consistency across services.
Ensure all services adhere to camelCase naming for JSON keys, regardless of implementation language. This reduces cognitive load for consumers and simplifies documentation, testing, and tooling.
6.4. Field naming guidelines.
6.4.1. Use camelCase for all keys.
6.4.2. Use descriptive, unambiguous names (e.g., createdAt, updatedBy, orderTotal).
6.4.3. Avoid abbreviations unless widely understood (e.g., id, url are acceptable).
6.4.4. Use boolean prefixes like is, has, or can for clarity (e.g., isActive, hasAccess).
7. Actions Beyond CRUD¶
7.1. If an operation doesn’t map cleanly to CRUD on a resource, prefer action subpaths on the resource (still nouns at the top level; the subpath can be a verb):
POST /v1/users/123/activate
POST /v1/orders/789/cancel
7.2. These remain exceptions; don’t turn the API into RPC.
8. HTTP Methods & Idempotency¶
8.1. GET - retrieve a resource or collection; must not have side effects. Idempotent.
8.2. POST - create a new resource in a collection or execute a non‑idempotent action. Returns 201 Created for creation.
8.3. PUT - full replacement of a resource; idempotent.
8.4. PATCH - partial update of a resource; not necessarily idempotent (aim for idempotency when practical).
8.5. DELETE - remove a resource; idempotent.
9. Status Codes & Headers¶
9.1. 200 OK (success with body), 204 No Content (success without body), 201 Created (on create; include Location header to the new resource).
9.2. 4xx for client errors (e.g., 400 Bad Request, 404 Not Found, 409 Conflict); 5xx for server errors. Use codes consistently across services.
10. Error Representation¶
10.1. Use a consistent JSON error envelope (e.g., code, message, details) across services; document it in the OpenAPI contract. Keep messages free of sensitive data.
10.2. Map validation issues to 400 with field‑level details; missing resources to 404; conflicts (e.g., version mismatches) to 409.
11. Versioning Strategy¶
11.1. Path versioning is required: /v1/.... Introduce /v2/... for breaking changes and support both during migration.
11.2. Avoid breaking changes solely to “comply” with guidelines if the API predates these rules; weigh impact with stakeholders.
12. Security Considerations in URL Design¶
12.1. Least disclosure: do not encode PII, tokens, or secrets in paths or query strings; use opaque IDs and authorization to control access.
12.2. Predictable hierarchies help defense: consistent path schemas improve logging, anomaly detection, and policy enforcement at gateways.
13. Recommended Resources¶
13.1. Microsoft REST API Guidelines: https://github.com/microsoft/api-guidelines
13.2. RESTful API Naming Conventions – https://restfulapi.net/resource-naming
13.3. Apidog Blog – https://apidog.com/blog/rest-api-url-best-practices-examples
13.4. DEV Community – https://dev.to/rahul_ranjan_7200/guide-to-rest-api-design-and-naming-conventions-46co
13.5. TheServerSide – https://www.theserverside.com/video/Top-REST-API-URL-naming-convention-standards
13.6. Daily.dev – https://daily.dev/blog/restful-api-design-best-practices-guide-2024
13.7. Tech Pulsion – https://techpulsion.com/rest-api-best-practices