Restful API Naming Convention Part2 Meeting Minutes
Meeting Info ¶
| Date | 2022-08-11 |
|---|---|
| Topic | Discussion on Restful API Naming Convention Part2 |
| Attendee | Calvin Yan, Rocky Chi, Daniel Zhou, Ted Zhao, Jackson Liu, Kevin Qian |
| Note Taker | Daniel Zhou |
| Timer | Jackson Liu |
| Duration | 60 minutes |
Meeting Agenda ¶
- Discussion on Restful API Naming Convention - part2 (40 min)
Meeting Minutes / Action Items ¶
Discussion on Restful API Naming Convention ¶
REST is an acronym for REpresentational State Transfer and an architectural style for distributed hypermedia systems.
Like other architectural styles, REST has its guiding principles and constraints. These principles must be satisfied if a service interface needs to be referred to as RESTful.
Architectural Constraints ¶
REST defines 6 architectural constraints which make any web service – a truly RESTful API.
1. What is a Resource? ¶
In REST, the primary data representation is called resource. Having a consistent and robust REST resource naming strategy – will prove one of the best design decisions in the long term.
1.1. Singleton and Collection Resources ¶
A resource can be a singleton or a collection.
For example, "customers" is a collection resource and "customer" is a singleton resource (in a banking domain).
We can identify "customers" collection resource using the URI "/customers". We can identify a single "customer" resource using the URI "/customers/{customerId}".
1.2. Collection and Sub-collection Resources ¶
A resource may contain sub-collection resources also.
For example, sub-collection resource "accounts" of a particular "customer" can be identified using the URN "/customers/{customerId}/accounts" (in a banking domain).
Similarly, a singleton resource "account" inside the sub-collection resource "accounts" can be identified as follows: "/customers/{customerId}/accounts/{accountId}".
1.3. URI ¶
REST APIs use Uniform Resource Identifiers (URIs) to address resources. REST API designers should create URIs that convey a REST API’s resource model to the potential clients of the API. When resources are named well, an API is intuitive and easy to use. If done poorly, that same API can be challenging to use and understand.
2. Best Practices ¶
2.1. Use nouns to represent resources [Mandatory] ¶
RESTful URI should refer to a resource that is a thing (noun) instead of referring to an action (verb) because nouns have properties that verbs do not have – similarly, resources have attributes. Some examples of a resource are:
- Users of the system
- User Accounts
- Network Devices etc.
and their resource URIs can be designed as below:
http://api.example.com/device-management/managed-devices http://api.example.com/device-management/managed-devices/{device-id} http://api.example.com/user-management/users http://api.example.com/user-management/users/{id}
For more clarity, let’s divide the resource archetypes into four categories (document, collection, store, and controller). Then it would be best if you always targeted to put a resource into one archetype and then use its naming convention consistently.
For uniformity’s sake, resist the temptation to design resources that are hybrids of more than one archetype.
Document
A document resource is a singular concept that is akin to an object instance or database record.
In REST, you can view it as a single resource inside resource collection. A document’s state representation typically includes both fields with values and links to other related resources.
Use "singular" name to denote document resource archetype.
http://api.example.com/device-management/managed-devices/{device-id} http://api.example.com/user-management/users/{id} http://api.example.com/user-management/users/admin
Collection
A collection resource is a server-managed directory of resources.
Clients may propose new resources to be added to a collection. However, it is up to the collection resource to choose to create a new resource or not.
A collection resource chooses what it wants to contain and also decides the URIs of each contained resource.
Use the "plural" name to denote the collection resource archetype.
http://api.example.com/device-management/managed-devices http://api.example.com/user-management/users http://api.example.com/user-management/users/{id}/accounts
Store
A store is a client-managed resource repository. A store resource lets an API client put resources in, get them back out, and decide when to delete them.
A store never generates new URIs. Instead, each stored resource has a URI. The URI was chosen by a client when the resource initially put it into the store.
Use "plural" name to denote store resource archetype.
http://api.example.com/song-management/users/{id}/playlists
Controller
A controller resource models a procedural concept. Controller resources are like executable functions, with parameters and return values, inputs, and outputs.
Use "verb" to denote controller archetype.
http://api.example.com/cart-management/users/{id}/cart/checkout http://api.example.com/song-management/users/{id}/playlist/play
2.2. Consistency is the key [Mandatory] ¶
Use forward slash (/) to indicate hierarchical relationships
The forward-slash (/) character is used in the path portion of the URI to indicate a hierarchical relationship between resources. e.g.
http://api.example.com/device-management http://api.example.com/device-management/managed-devices http://api.example.com/device-management/managed-devices/{id} http://api.example.com/device-management/managed-devices/{id}/scripts http://api.example.com/device-management/managed-devices/{id}/scripts/{id}
Do not use trailing forward slash (/) in URIs
As the last character within a URI's path, a forward slash (/) adds no semantic value and may confuse. It’s better to drop it from the URI.
http://api.example.com/device-management/managed-devices/ http://api.example.com/device-management/managed-devices /*This is much better version*/
Use hyphens (-) to improve the readability of URIs
To make your URIs easy for people to scan and interpret, use the hyphen (-) character to improve the readability of names in long path segments.
http://api.example.com/device-management/managed-devices/ http://api.example.com/device-management/managed-devices /*This is much better version*/
Do not use underscores ( _ )
It’s possible to use an underscore in place of a hyphen to be used as a separator – But depending on the application’s font, it is possible that the underscore (_) character can either get partially obscured or completely hidden in some browsers or screens.
To avoid this confusion, use hyphens (-) instead of underscores ( _ ).
http://api.example.com/inventory-management/managed-entities/{id}/install-script-location //More readable http://api.example.com/inventory-management/managedEntities/{id}/installScriptLocation //Less readable
Use lowercase letters in URIs
When convenient, lowercase letters should be consistently preferred in URI paths.
http://api.example.org/my-folder/my-doc //1 HTTP://API.EXAMPLE.ORG/my-folder/my-doc //2 http://api.example.org/My-Folder/my-doc //3
In the above examples, 1 and 2 are the same but 3 is not as it uses My-Folder in capital letters.
2.3 Do not use file extensions [Mandatory] ¶
File extensions look bad and do not add any advantage. Removing them decreases the length of URIs as well. No reason to keep them.
Apart from the above reason, if you want to highlight the media type of API using file extension, then you should rely on the media type, as communicated through the Content-Type header, to determine how to process the body’s content.
http://api.example.com/device-management/managed-devices.xml /*Do not use it*/ http://api.example.com/device-management/managed-devices /*This is correct URI*/
2.4 Never use CRUD function names in URIs [Mandatory] ¶
We should not use URIs to indicate a CRUD function. URIs should only be used to uniquely identify the resources and not any action upon them.
We should use HTTP request methods to indicate which CRUD function is performed.
HTTP GET http://api.example.com/device-management/managed-devices //Get all devices HTTP POST http://api.example.com/device-management/managed-devices //Create new Device HTTP GET http://api.example.com/device-management/managed-devices/{id} //Get device for given Id HTTP PUT http://api.example.com/device-management/managed-devices/{id} //Update device for given Id HTTP DELETE http://api.example.com/device-management/managed-devices/{id} //Delete device for given Id
2.5 Use query component to filter URI collection [Mandatory] ¶
Often, you will encounter requirements where you will need a collection of resources sorted, filtered, or limited based on some specific resource attribute.
For this requirement, do not create new APIs – instead, enable sorting, filtering, and pagination capabilities in resource collection API and pass the input parameters as query parameters. e.g.
http://api.example.com/device-management/managed-devices http://api.example.com/device-management/managed-devices?region=USA http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date
3. Accept and respond with JSON [Mandatory] ¶
REST APIs should accept JSON for request payload and also send responses to JSON. JSON is the standard for transferring data. Almost every networked technology can use it: JavaScript has built-in methods to encode and decode JSON either through the Fetch API or another HTTP client. Server-side technologies have libraries that can decode JSON without doing much work.
There are other ways to transfer data. XML isn’t widely supported by frameworks without transforming the data ourselves to something that can be used, and that’s usually JSON. We can’t manipulate this data as easily on the client-side, especially in browsers. It ends up being a lot of extra work just to do normal data transfer.
Form data is good for sending data, especially if we want to send files. But for text and numbers, we don’t need form data to transfer those since—with most frameworks—we can transfer JSON by just getting the data from it directly on the client side. It’s by far the most straightforward to do so.
To make sure that when our REST API app responds with JSON that clients interpret it as such, we should set Content-Type in the response header to application/json after the request is made. Many server-side app frameworks set the response header automatically. Some HTTP clients look at the Content-Type response header and parse the data according to that format.
The only exception is if we’re trying to send and receive files between client and server. Then we need to handle file responses and send form data from client to server. But that is a topic for another time.
We should also make sure that our endpoints return JSON as a response. Many server-side frameworks have this as a built-in feature.
4. Handle errors gracefully and return standard error codes [Mandatory] ¶
To eliminate confusion for API users when an error occurs, we should handle errors gracefully and return HTTP response codes that indicate what kind of error occurred. This gives maintainers of the API enough information to understand the problem that’s occurred. We don’t want errors to bring down our system, so we can leave them unhandled, which means that the API consumer has to handle them.
Common error HTTP status codes include:
- 400 Bad Request – This means that client-side input fails validation.
- 401 Unauthorized – This means the user isn’t authorized to access a resource. It usually returns when the user isn’t authenticated.
- 403 Forbidden – This means the user is authenticated, but it’s not allowed to access a resource.
- 404 Not Found – This indicates that a resource is not found.
- 500 Internal server error – This is a generic server error. It probably shouldn’t be thrown explicitly.
- 502 Bad Gateway – This indicates an invalid response from an upstream server.
- 503 Service Unavailable – This indicates that something unexpected happened on server side (It can be anything like server overload, some parts of the system failed, etc.).
Action output ¶
- New UI needs to be compatible with old API response.
- It will be better we use version to control API, like /v1/, /v2/. Or add version in header.
- We need to think more how to apply HATEOAS in our project. It is a good case.
- We can refer to https://developer.webex.com/docs/api/v1/ for API definition standard.
- We can have a sharing meeting after we complete the Restful API rule definitions.