Best Practices for Naming REST API URIs: Difference between revisions
(68 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
REST APIs use [[URI#Overview|Uniform Resource Identifiers (URIs)]] to address resources. | REST APIs use [[URI#Overview|Uniform Resource Identifiers (URIs)]] to address resources. | ||
=Use Forward Slash to Indicate a Hierarchical Relationship= | =General URI Rules= | ||
==Use Forward Slash to Indicate a Hierarchical Relationship== | |||
The forward slash (/) character is used in the [[URI#Path|path]] portion of the URI to indicate a hierarchical relationship between resources. Also see [[#Resource_Modeling|Resource Modeling]] below. | The forward slash (/) character is used in the [[URI#Path|path]] portion of the URI to indicate a hierarchical relationship between resources. Also see [[#Resource_Modeling|Resource Modeling]] below. | ||
Line 19: | Line 19: | ||
</font> | </font> | ||
=A Trailing Forward Slash Should Not Be Included in URIs= | ==A Trailing Forward Slash Should Not Be Included in URIs== | ||
Every character within a URI counts towards a resource's unique identity. If the URIs differ, then so do the resources, and vice-versa. Even if the REST API implementation discards the trailing forward slashes, the definition of the REST API must communicate clean URIs. For example, an API implementation may redirect clients that use a forward slash to the URI without forward slash using a [[HTTP_Status_Codes#301_Moved_Permanently|HTTP 301]] response code. | Every character within a URI counts towards a resource's unique identity. If the URIs differ, then so do the resources, and vice-versa. Even if the REST API implementation discards the trailing forward slashes, the definition of the REST API must communicate clean URIs. For example, an API implementation may redirect clients that use a forward slash to the URI without forward slash using a [[HTTP_Status_Codes#301_Moved_Permanently|HTTP 301]] response code. | ||
=<span id='Hyphen'></span>Separate Words with Hyphens= | ==<span id='Hyphen'></span>Separate Words with Hyphens== | ||
When a REST API URI contains multiple words in a path segment, separate the words with hyphens. It's a good way to make the URI easier to read and is a universal method that everyone can understand. It's generally accepted that a hyphen is clearer and more user-friendly than [[#Underscore|underscores]] (first_name) or camel case (firstName), which is discouraged due to its use of capital letters. | When a REST API URI contains multiple words in a path segment, separate the words with hyphens. It's a good way to make the URI easier to read and is a universal method that everyone can understand. It's generally accepted that a hyphen is clearer and more user-friendly than [[#Underscore|underscores]] (first_name) or camel case (firstName), which is discouraged due to its use of capital letters. | ||
=<span id='Underscore'></span>Do Not Use Underscores= | ==<span id='Underscore'></span>Do Not Use Underscores== | ||
One practical reason is that the underscored may get partially obscured in the UIs that render clickable URIs, depending on the fonts that are used. To avoid this, use [[#Hyphen|hyphens]] to separate words. | One practical reason is that the underscored may get partially obscured in the UIs that render clickable URIs, depending on the fonts that are used. To avoid this, use [[#Hyphen|hyphens]] to separate words. | ||
=Prefer Lowercase Letters= | ==Prefer Lowercase Letters== | ||
The URIs are case-sensitive, except for the scheme and host components. | The URIs are case-sensitive, except for the scheme and host components. | ||
Lowercase is preferred, if practical, because capital letters can sometimes cause problems. | Lowercase is preferred, if practical, because capital letters can sometimes cause problems. | ||
=File Extensions Should Not Be Included in URIs= | ==File Extensions Should Not Be Included in URIs== | ||
A REST API should not include artificial file extensions in URIs to indicate the format of a message's entity body. Instead, they should rely on media type, as communicated through the <code>Content-Type</code> header. | A REST API should not include artificial file extensions in URIs to indicate the format of a message's entity body. Instead, they should rely on media type, as communicated through the <code>Content-Type</code> header. | ||
Line 51: | Line 46: | ||
Many REST APIs have an associated website, known as developer portal, to help on-board new clients with documentation, etc. Conventionally it is named using the "developer" subdomain: developer.accounting.example.com. | Many REST APIs have an associated website, known as developer portal, to help on-board new clients with documentation, etc. Conventionally it is named using the "developer" subdomain: developer.accounting.example.com. | ||
=Resource | =<span id='Resource_Archetype'></span>Resource Archetypes= | ||
The URI [[URI#Path|path]] conveys a REST API's resource model, which each forward slash separated path segment corresponding to a unique resource within the model hierarchy. Resource modeling establishes the key API's concepts, and it is similar to data modeling in a relational database or class hierarchy modeling in an object-oriented system. Assigning meaningful values for each path segment helps to communicate the hierarchical structure of the REST API resource model. | |||
For example in this URI <code>http:://api.directory.example.com/departments/marketing/teams/{id}</code>, each of the path elements identifies an addressable resource: | |||
<font size=-2> | |||
http:://api.directory.example.com/departments/marketing/teams | |||
http:://api.directory.example.com/departments/marketing | |||
http:://api.directory.example.com/departments | |||
http:://api.directory.example.com | |||
</font> | |||
It is useful to assign every resource modeled in a system to one of four archetypes: [[#Document|document]], [[#Collection|collection]], [[#Store|store]] and [[#Controller|controller]]. Resist the temptation to design resources as hybrids of more than one archetypes. If that situation arises, consider designing separate resources that are either part of a hierarchy, or in relationships, modeled as links. | |||
==Document== | |||
A document resource models a singular concept in the system exposed by the REST API, similar conceptually with an object instance in an object-oriented system. A document's state includes '''fields''' with values, and '''links''' to related resources, modeling the relationships that exist between instances. The following URIs identifies a document resource: | |||
<font size=-2> | |||
http:://api.directory.example.com/departments/marketing/teams/<b>advertising</b> | |||
http:://api.directory.example.com/departments/<b>marketing</b> | |||
</font> | |||
A document may have child resources that represent different subordinate concepts. | |||
===<span id='A8987'></span>Use Singular Nouns or Identity-Based Values for Document Names=== | |||
A URI representing a document resource should be named with a singular noun or noun phrase path segment: | |||
<font size=-2> | |||
http:://api.directory.example.com/departments/<b>marketing</b> | |||
</font> | |||
The [[URI#URI_Template|URI Template]] syntax allows for dynamic path elements, automatically filled in with some identifier that provides the URI its uniqueness. When the instance corresponding to a document resource has a unique ID, that unique ID can be used in the path segment corresponding to the document resource: | |||
<font size=-2> | |||
http:://api.directory.example.com/departments/<b>${deptID}</b> | |||
http:://api.directory.example.com/departments/<b>1022</b> | |||
</font> | |||
===REST APIs and IDs=== | |||
A REST API client must consider the full URI to be the '''only''' meaningful resource identifier. Although other backend systems identifiers, such as database IDs may appear in the URI path, they are meaningless to the client code and they shouldn't be handled in isolation. By establishing the URIs as the only IDs, a REST API backend implementation may evolve over time without impacting its clients. | |||
The URI [[ | ==Collection== | ||
A collection is a '''system-managed''' directory of resources. Clients may propose new resources to be added to the collection, but it is up to the collection resource to decide whether a new resource is created or not. The collection chooses what it wants to contain, and also decides the URI of each contained resource. The following URIs represent collections: | |||
<font size=-2> | |||
http:://api.directory.example.com/departments/marketing/<b>teams</b> | |||
http:://api.directory.example.com/<b>departments</b> | |||
</font> | |||
Collections may be [[#Filter|filtered]] or [[#Paginate|paginated]] using URI queries. | |||
===<span id='A92'></span>Use Plural Nouns for Collection Names=== | |||
A URI identifying a collection should be named with a plural noun, or noun phrase path segment. A collection's name should be chosen to reflect what it uniformly contains. | |||
<font size=-2> | |||
http:://api.directory.example.com/<b>departments</b> | |||
</font> | |||
==Store== | |||
A store is a '''client-managed''' resource repository. A store resource lets the client put resources in, via API calls, to get them back out and delete them when the client wishes. On their own, stores do not create new resources. Therefore, a store never generates new URIs. Instead, each stored resource has a URI that was chosen by the client when it was initially put in the store. | |||
An example of a request initiated by a user ("1122") to insert a document resources name "chocolate" in the user's store of "favorites": | |||
<font size=-2> | |||
http:://api.directory. | PUT /users/1122/<b><font color='teal'>favorites</font></b>/<b>chocolate</b> | ||
</font> | |||
Collections may be [[#Filter|filtered]] or [[#Paginate|paginated]] using URI queries. | |||
===<span id='A93'></span>Use Plural Nouns for Store Names=== | |||
A URI identifying a store should be named with a plural noun, or noun phrase path segment. A store's name should be chosen to reflect what it uniformly contains. | |||
<font size=-2> | |||
http:://api.directory.example.com/users/1133/<b>favorites</b> | |||
</font> | |||
=Use | ==Controller== | ||
A controller resource models a '''procedural concept''' that goes beyond those that can be modeled with HTTP operations GET, POST, PUT, PATCH, DELETE, etc. Controller resources are similar to executable functions, with parameters and return values. The REST API relies on controller resources to perform application-specific actions that cannot be mapped onto CRUD operation. Controller names typically appear as the last segment in a URI path, with no child resources to follow them in the hierarchy. | |||
<font size=-2> | |||
POST /alerts/245743/<b>resend</b> | |||
</font> | |||
===<span id='A94'></span>Use Verbs for Controller Names=== | |||
A URI identifying a controller resource is conceptually similar to a function and it should be named accordingly with a verb: | |||
<font size=-2> | |||
http:://api.directory.example.com/alerts/1133/<b>resend</b> | |||
</font> | |||
=<span id='Resource_Modeling'></span>Resource Modeling Rules= | |||
==Use Singular Nouns or Identity-Based Values for Document Names== | |||
See [[#A8987|Use Singular Nouns or Identity-Based Values for Document Names]] above. | |||
==Use Plural Nouns for Collection Names== | |||
See [[#A92|Use Plural Nouns for Collection Names]] above. | |||
==Use Plural Nouns for Store Names== | |||
See [[#A93|Use Plural Nouns for Store Names]] above. | |||
==Use Verbs for Controller Names== | |||
See [[#A94|Use Verbs for Controller Names]] above. | |||
==CRUD Operation Names Should Not Be Used in URIs== | |||
= | URIs should not be used to indicate that a CRUD operation is performed. The URI should be the resource identifier, and the operation should be mapped onto HTTP request methods. | ||
=URI Query Rules= | |||
An URI may contain an optional [[URI#Query|query]]. | |||
<font size=-1> | |||
<font color=darkgray>scheme "://" authority "/" path <font color=steelblue>[ "?" query ]</font> [ "#" fragment </font> | |||
</font> | |||
The query components of a URI contain a set of parameters to be interpreted as a variation or derivative of the resource that is hierarchically identified by the path component. The query can provide clients with additional interaction capabilities such as searching and filtering. | |||
==<span id='Filter'></span>The Query May be Used to Filter Collections or Stores== | |||
The query component is a natural fit for supplying search or filtering criteria to a [[#Collection|collection]] or [[#Store|store]] and it should used as such. When the filtering requirements exceeds the simple formatting capabilities of the URI query, consider using a [[#Controller|controller resource]] that partners with the collection or store. | |||
==<span id='Paginate'></span>The Query Should be Used to Paginate Collection or Store Results== | |||
A REST API should use the query component of the URI to paginate [[#Collection|collections]] or [[#Store|stores]]. It should use the following parameters: <code>pageSize</code> to specify the maximum number of elements to be returned in response, and <code>pageStartIndex</code> to specify the zero-based index of the first element to return in response. When the pagination requirements exceeds the simple formatting capabilities of the URI query, consider using a [[#Controller|controller resource]] that partners with the collection or store. |
Latest revision as of 23:49, 14 February 2024
External
- REST API Design Rulebook by Mark Masse, O'Reilly, Chapter 2. Identifier Design with URIs.
Internal
Overview
REST APIs use Uniform Resource Identifiers (URIs) to address resources.
General URI Rules
Use Forward Slash to Indicate a Hierarchical Relationship
The forward slash (/) character is used in the path portion of the URI to indicate a hierarchical relationship between resources. Also see Resource Modeling below.
Example:
http:://api.canvas.restapi.org/shapes/polygons/quadrilaterals/squares
A Trailing Forward Slash Should Not Be Included in URIs
Every character within a URI counts towards a resource's unique identity. If the URIs differ, then so do the resources, and vice-versa. Even if the REST API implementation discards the trailing forward slashes, the definition of the REST API must communicate clean URIs. For example, an API implementation may redirect clients that use a forward slash to the URI without forward slash using a HTTP 301 response code.
Separate Words with Hyphens
When a REST API URI contains multiple words in a path segment, separate the words with hyphens. It's a good way to make the URI easier to read and is a universal method that everyone can understand. It's generally accepted that a hyphen is clearer and more user-friendly than underscores (first_name) or camel case (firstName), which is discouraged due to its use of capital letters.
Do Not Use Underscores
One practical reason is that the underscored may get partially obscured in the UIs that render clickable URIs, depending on the fonts that are used. To avoid this, use hyphens to separate words.
Prefer Lowercase Letters
The URIs are case-sensitive, except for the scheme and host components.
Lowercase is preferred, if practical, because capital letters can sometimes cause problems.
File Extensions Should Not Be Included in URIs
A REST API should not include artificial file extensions in URIs to indicate the format of a message's entity body. Instead, they should rely on media type, as communicated through the Content-Type
header.
Authority Rules
APIs Should Use Consistent Subdomain Names
The top-level domain and first subdomain name (example: accounting.example.com) should identity the service owner. The full domain name of an API should add a subdomain named "api": api.accounting.example.com.
Developer Portal Names
Many REST APIs have an associated website, known as developer portal, to help on-board new clients with documentation, etc. Conventionally it is named using the "developer" subdomain: developer.accounting.example.com.
Resource Archetypes
The URI path conveys a REST API's resource model, which each forward slash separated path segment corresponding to a unique resource within the model hierarchy. Resource modeling establishes the key API's concepts, and it is similar to data modeling in a relational database or class hierarchy modeling in an object-oriented system. Assigning meaningful values for each path segment helps to communicate the hierarchical structure of the REST API resource model.
For example in this URI http:://api.directory.example.com/departments/marketing/teams/{id}
, each of the path elements identifies an addressable resource:
http:://api.directory.example.com/departments/marketing/teams http:://api.directory.example.com/departments/marketing http:://api.directory.example.com/departments http:://api.directory.example.com
It is useful to assign every resource modeled in a system to one of four archetypes: document, collection, store and controller. Resist the temptation to design resources as hybrids of more than one archetypes. If that situation arises, consider designing separate resources that are either part of a hierarchy, or in relationships, modeled as links.
Document
A document resource models a singular concept in the system exposed by the REST API, similar conceptually with an object instance in an object-oriented system. A document's state includes fields with values, and links to related resources, modeling the relationships that exist between instances. The following URIs identifies a document resource:
http:://api.directory.example.com/departments/marketing/teams/advertising http:://api.directory.example.com/departments/marketing
A document may have child resources that represent different subordinate concepts.
Use Singular Nouns or Identity-Based Values for Document Names
A URI representing a document resource should be named with a singular noun or noun phrase path segment:
http:://api.directory.example.com/departments/marketing
The URI Template syntax allows for dynamic path elements, automatically filled in with some identifier that provides the URI its uniqueness. When the instance corresponding to a document resource has a unique ID, that unique ID can be used in the path segment corresponding to the document resource:
http:://api.directory.example.com/departments/${deptID} http:://api.directory.example.com/departments/1022
REST APIs and IDs
A REST API client must consider the full URI to be the only meaningful resource identifier. Although other backend systems identifiers, such as database IDs may appear in the URI path, they are meaningless to the client code and they shouldn't be handled in isolation. By establishing the URIs as the only IDs, a REST API backend implementation may evolve over time without impacting its clients.
Collection
A collection is a system-managed directory of resources. Clients may propose new resources to be added to the collection, but it is up to the collection resource to decide whether a new resource is created or not. The collection chooses what it wants to contain, and also decides the URI of each contained resource. The following URIs represent collections:
http:://api.directory.example.com/departments/marketing/teams http:://api.directory.example.com/departments
Collections may be filtered or paginated using URI queries.
Use Plural Nouns for Collection Names
A URI identifying a collection should be named with a plural noun, or noun phrase path segment. A collection's name should be chosen to reflect what it uniformly contains.
http:://api.directory.example.com/departments
Store
A store is a client-managed resource repository. A store resource lets the client put resources in, via API calls, to get them back out and delete them when the client wishes. On their own, stores do not create new resources. Therefore, a store never generates new URIs. Instead, each stored resource has a URI that was chosen by the client when it was initially put in the store.
An example of a request initiated by a user ("1122") to insert a document resources name "chocolate" in the user's store of "favorites":
PUT /users/1122/favorites/chocolate
Collections may be filtered or paginated using URI queries.
Use Plural Nouns for Store Names
A URI identifying a store should be named with a plural noun, or noun phrase path segment. A store's name should be chosen to reflect what it uniformly contains.
http:://api.directory.example.com/users/1133/favorites
Controller
A controller resource models a procedural concept that goes beyond those that can be modeled with HTTP operations GET, POST, PUT, PATCH, DELETE, etc. Controller resources are similar to executable functions, with parameters and return values. The REST API relies on controller resources to perform application-specific actions that cannot be mapped onto CRUD operation. Controller names typically appear as the last segment in a URI path, with no child resources to follow them in the hierarchy.
POST /alerts/245743/resend
Use Verbs for Controller Names
A URI identifying a controller resource is conceptually similar to a function and it should be named accordingly with a verb:
http:://api.directory.example.com/alerts/1133/resend
Resource Modeling Rules
Use Singular Nouns or Identity-Based Values for Document Names
See Use Singular Nouns or Identity-Based Values for Document Names above.
Use Plural Nouns for Collection Names
See Use Plural Nouns for Collection Names above.
Use Plural Nouns for Store Names
See Use Plural Nouns for Store Names above.
Use Verbs for Controller Names
See Use Verbs for Controller Names above.
CRUD Operation Names Should Not Be Used in URIs
URIs should not be used to indicate that a CRUD operation is performed. The URI should be the resource identifier, and the operation should be mapped onto HTTP request methods.
URI Query Rules
An URI may contain an optional query.
scheme "://" authority "/" path [ "?" query ] [ "#" fragment
The query components of a URI contain a set of parameters to be interpreted as a variation or derivative of the resource that is hierarchically identified by the path component. The query can provide clients with additional interaction capabilities such as searching and filtering.
The Query May be Used to Filter Collections or Stores
The query component is a natural fit for supplying search or filtering criteria to a collection or store and it should used as such. When the filtering requirements exceeds the simple formatting capabilities of the URI query, consider using a controller resource that partners with the collection or store.
The Query Should be Used to Paginate Collection or Store Results
A REST API should use the query component of the URI to paginate collections or stores. It should use the following parameters: pageSize
to specify the maximum number of elements to be returned in response, and pageStartIndex
to specify the zero-based index of the first element to return in response. When the pagination requirements exceeds the simple formatting capabilities of the URI query, consider using a controller resource that partners with the collection or store.