[ADP-308] Resource Design Misc
Defining and Naming Resources
SHOULD define useful resources.
Resources should be defined to cover 90% of all client use cases. A useful resource should contain as much information as necessary but as little as possible. To support the remaining 10%, allow clients to specify their needs for more/less information by supporting filtering and embedding.
Example:
http/events /users
MUST use domain-specific resource names.
API resources represent elements of the application’s domain model. Using domain-specific nomenclature for resource names helps developers understand the functionality and semantics of your resources. For example, "sales-order-items" is superior to "order-items" as it clearly indicates the business object it represents. Similarly, "items" is too general.
Example:
http/project-tasks /financial-reports /employee-records
SHOULD model complete business processes.
An API should encapsulate the complete business processes, including all resources representing the process. This helps clients understand the business process, fosters a consistent design, and eliminates implicit dependencies between APIs. Additionally, it prevents services from being designed as thin wrappers around databases, which often shifts business logic to the clients.
Example:
http/workflows /workflows/{workflow-id}/steps /workflows/{workflow-id}/actions
Resource Path Design
MUST identify resources and sub-resources via path segments.
Some API resources may contain or reference sub-resources. Embedded sub-resources, which are not top-level resources, are parts of a higher-level resource and cannot be used outside its scope. Sub-resources should be referenced by their name and identifier in the path segments as follows:
http/resources/{resource-id}/sub-resources/{sub-resource-id}
Aim for intuitively understandable URLs where each sub-path is a valid reference to a resource or a set of resources. For instance, if
/partners/{partner-id}/addresses/{address-id}
is valid, then/partners/{partner-id}/addresses
,/partners/{partner-id}
, and/partners
should also be valid.Example:
http/orders/5678/items/1234 /orders/5678/items /orders/5678 /orders
MAY expose compound keys as resource identifiers.
If a resource is best identified by a compound key consisting of multiple other resource identifiers, it is allowed to reuse the compound key in its natural form containing slashes in the resource path:
http/resources/{compound-key-1}[delim-1]...[delim-n-1]{compound-key-n}
Example paths:
http/tickets/{event-id}/{seat-number} /tickets/{event-id}/{seat-number}/details /assignments/{course-id}/{student-id}/grades /assignments/{course-id}/{student-id}/submissions/{submission-id}
MAY consider using (non-) nested URLs.
If a sub-resource is only accessible via its parent resource and may not exist without it, consider using a nested URL structure:
http/projects/{project-id}/milestones/{milestone-id}
If the resource can be accessed directly via its unique id, then it should be exposed as a top-level resource:
http/projects/1234 /milestones/5678
Resource Complexity and Levels
- SHOULD limit the number of resource types:
To maintain manageability and service evolution, follow "functional segmentation" and "separation of concern" design principles. Avoid mixing different business functionalities in the same API definition. Aim to limit the number of resource types exposed via an API. For example, the following resources count as three resource types: students, courses, and student’s related courses.
http/students /students/{id} /students/{id}/settings /students/{id}/courses /students/{id}/courses/{course-id} /courses /courses/{course-id}
/students
and/students/id
are bothstudent
resource./students/{id}/settings
where settings won’t have an identifier and cannot exist withoutstudent
, it is treated as part of thestudent
resource./students/{id}/courses
and/students/{id}/courses/{course-id}
is acourse
type resource which has 1 to 1 and 1 to many relationship with the specific student/student/{id}
.
- SHOULD limit the number of sub-resource levels:
Use sub-resources if their lifecycle is loosely coupled to the main resource. You should use no more than three sub-resource (nesting) levels, as more levels increase API complexity and URL path length.
Example:
DON’T
http/libraries/{library-id}/books/{book-id}/chapters/{chapter-id} /companies/{company-id}/departments/{department-id}/employees/{employee-id}