Name resources, not actions
REST URLs should describe things. Start with nouns that reflect the domain: `/users`, `/devices`, `/orders`. This keeps the API intuitive and stable.
Actions belong to HTTP verbs, not to the path. `DELETE /orders/987` is clearer than `/orders/987/cancel`.
Choose a consistent pluralization
Most APIs use plural nouns for collections (`/users`) and a single ID for the item (`/users/123`). This is easy to learn and widely accepted.
The key is consistency. If you decide to use singular nouns, do it everywhere.
Keep hierarchies shallow
Nested paths express relationships, like `/users/123/orders`. This is fine when the child is strongly tied to the parent.
Avoid deep nesting. More than two levels creates coupling and makes URLs fragile when your model evolves.
Use query parameters for filters
Filtering, sorting, and pagination belong in query parameters: `/orders?status=paid&sort=-created_at&page=2`.
This keeps paths focused on identity and lets you extend filters without breaking clients.
Pick a casing convention
URLs should follow a single casing style. Kebab-case is common and readable. Query parameters are often snake_case.
The exact choice matters less than consistency. Inconsistent casing slows down integrations.
Design for change
Your API will evolve. Avoid encoding internal details like table names or service boundaries into URLs.
Use domain language that stays stable as your backend changes. This makes refactors less painful.
Examples that scale
A clean design: `/devices`, `/devices/{id}`, `/devices/{id}/state`, `/alerts`. Each endpoint represents an object with a clear lifecycle.
When you add features, reuse the same patterns. Consistency is what makes a REST API feel professional.
