Small guide on resource URL design for REST API
Understanding and applying resource relationships is critical to a great API design.
Analyzing relationship between resources allows us to define a better URL structure that will be clear and easier to under for all the developers that will consume it. Basically , we need to determine if all resources belong at the top level of the resource hierarchy, or if some of them must be nested under other resources (named "parent resources").
Once defined the relationships between the resources, we can define URLs structure and the API will be "self explanatory".
Let's dive more in detail with a simple example. Suppose we have to create an API that allows us to manage projects and tasks within a company. In this case we'll have two resources: Projects and Tasks. Based on the way the company runs its projects, we can identify several possibility of modeling:
- A task can exists alone and it is not mandatory that it belongs to a specific project. In this case there is no relationship between Tasks and Projects and the two resources are independent. Consequently, the URLs will be at the "top level" in both cases:
- /tasks
- /projects
- A task must belong to a specific project. In this scenario there is a dependent relationship between the resource and a tasks is sibling resource of a specif instance of projects, so the URL structure will be something like
- /projects
- /projects/{project_id}/tasks
Also, there is third type of relationship: the associative relationship. It is the case where two resources are independant but one of the two may also be considered as nested resource under the other (typically using a different name in order to avoid confusion with naming). In our example we could add the concept of Users. A user is an independent resource but it can be assigned to a project and become a member of that project. In this case we can model an associative relationship between Users and Projects and we should expose a URL structure like:
- /projects
- /users
- /projects/{project_id}/members
A good API design should always take care of these concepts and I usually follow these best practice in our projects.