Resource Naming and URL Structure
Designing an intuitive and logical URL structure is a cornerstone of building well-designed REST APIs. Below is a detailed explanation of key principles and conventions-
URL Patterns and Conventions
URLs should represent resources (nouns) rather than actions (verbs).
Name should represent who rather than what.
Use lowercase letters and hyphens (
-
) to separate words for readability. Avoid camelCase or underscores.Correct:
/books
/user-profiles , /users/
Incorrect:
/getBooks
/userProfiles
or/user_profiles
.
Use plural nouns for collections and singular nouns for individual resources.
/users
→ Represents the collection of users./users/{userId}
→ Represents a single user.
Do not use file extensions like
.json
or.xml
in URLs. Content negotiation should be handled via headers.Avoid deeply nested structures and long paths.
Example: /orders/{orderId}/items
instead of /user/{userId}/order/{orderId}/item/{itemId}
.
Resource Identification
Show relationships explicitly using paths.
/users/{userId}/orders
→ Fetches all orders for a specific user.
Represent a list of resources using plural nouns. e.g.
/products
Use a unique identifier (e.g., ID) to fetch a single resource.
/products/{productId}
→ Fetches details of a specific product.
If resources have a natural compound identifier, include it in the URL.
/countries/{countryCode}/states/{stateCode}
.
Nested Resources Handling
Nested resources should reflect a hierarchy between parent and child resources. Keep nesting manageable (1-2 levels) to avoid overly complex URLs.
Use for clear parent-child relationships.
/authors/{authorId}/books
→ Books written by a specific author./departments/{deptId}/employees
→ Employees in a department.
Deep nesting makes URLs cumbersome. Instead, flatten the structure and use query parameters or separate endpoints for complex relationships.
Too Deep:
/users/{userId}/projects/{projectId}/tasks/{taskId}
Better:
/tasks?userId={userId}&projectId={projectId}
Ensure child resources can be accessed independently when needed.
/books/{bookId}
should retrieve the book without requiring/authors/{authorId}/books/{bookId}
.
Query Parameter Usage
Query parameters allow filtering, searching, sorting, and pagination without cluttering the URL path.
Examples:
Filter and Searching:
/products?category=electronics
→ Fetch products in the "electronics" category./products?search=smartphone
→ Search for products with "smartphone"
Sorting:
/products?sort=price
→ Sort products by price in ascending order./products?sort=-price
→ Sort products by price in descending order (prefix with-
for descending).
Pagination:
/users?page=2&size=10
→ Fetch the second page of 10 users./products?limit=25&offset=50
→ Fetch 25 products starting from the 50th./products?category=electronics&price[lt]=1000&brand=apple
→ Multiple filters
Boolean & Range queries :
/orders?shipped=true
→ Fetch only shipped orders./products?price[gte]=100&price[lte]=500
→ Fetch products priced between 100 and 500.
Custom Operations:
/users/export?format=csv
→ Export users in CSV format.
Example
Service-to-Service Communication
When designing URLs for microservices, consider the service boundaries:
Aggregate Resources
When dealing with complex business entities that span multiple services:
Cross-Cutting Concerns
For functionalities that span multiple services:
Resource State Transitions
For handling complex state transitions in distributed systems:
API Gateway Level URLs
Best Practices Summary:
Use plural nouns for collection resources
Use nouns, not verbs in URLs
Use hierarchical structure for related resources
Use query parameters for filtering, sorting, and pagination
Keep URLs as simple and logical as possible
Maintain consistency across all services
Consider service boundaries when designing URLs
Use appropriate HTTP methods instead of encoding actions in URLs
Handle cross-cutting concerns at appropriate levels
Design with API evolution in mind
A well-designed URL structure improves API usability, readability, and maintainability. Would you like examples of these principles implemented in Spring Boot code?
Last updated