This is the second article in a five part series on RESTful APIs.
Architecture style, stateless, and design constraints
Everybody uses REST applications to access information from the internet. REST APIs are everywhere, in news sites, blogs, social media, etc.
But what is REST? REST is an application architecture style defined by Roy Fielding in his dissertation from 2000.
Every style implies constraints. If you have no constraints, you have no style. To be considered a RESTful API, it has to satisfy all the constraints that define it. If the style satisfies some constraints, but not all of them, then it can be considered REST-based.
1. Use of uniform interface – This means that whatever service you are creating (news sites, forums, social networks) and whatever client consumes the API, it has the same interface. You use the same interface by having an URL for a resource and manipulating it via HTTP verbs like GET and POST. Request, type, resource, and content and format. We need the JSON format. Resource manipulation through representation. HATEOS. Once it has access, it can see everything. Does not care who consumes the data and how. Web app, mobile app, IoT device.
2. Server-client architecture – Having the server-client architecture provides several benefits, suchs as loose coupling between server and client, a highly portable system, and a clear separation of concerns between the content and the presentation.
3. Stateless – The state should be kept on the client, separation of concerns, redeploy fast, scale up as needed. All requests should be self-contained. Sessions are not stateless. If something is stored on the server for requests, then this constraint is violated.
4. Caching – All resources should be cached by default, unless explicitly indicated otherwise. Performance optimization for rest. ETag header is used.
5. Layered system – This implies the composition of higher-order systems.
Richardson maturity model
According to the Richardson maturity model, there are 4 levels for REST APIs:
1. Everything is a single endpoint, no resources, no verbs, no HATEOS (Hypermedia as the Engine of Application State).
2. Uses resources properly but not verbs and no HATEOS. Basically dividing the app complexity in more resources to be used.
3. Uses resources, status codes, and verbs properly but no HATEOS, applying a uniform interface for the resources that were divided from the business model.
4. Uses resources, verbs, and HATEOS properly, applying discoverability in the application.
There is no strict requirement that REST should be done via HTTP. REST is just an architectural style. A convenient pairing has been formed between the REST style, the HTTP protocol, and networked/cloud applications.
REST and HTTP have such a strong synergy that the entire internet is, at its core, a giant REST application, with small exceptions, and varying maturity levels.
Both HTTP and REST have no memory of previous requests.
Everything can be a resource, usually in the domain of the problem you should find nouns for resources(sometimes adjectives) and HTTP verbs for actions.
There are 2 kinds of resources:
- collections, which implies a list of elements.
- singletons, which are a specific instance of the resource.
Resources can be narrowed down through specificity in the API. Usually, endpoints are used in singular if they represent a resource and plural if they represent a collection, a verb might be used for some action that is not CRUD, checkout for example.
/user => collection of users
/user/1234 => a unique user-specified via id
/user/happy/1234 => a happy user with a specific id, singleton
/cart/1234/checkout => a happy user with a specific id, singleton
The resource is the data at its specific URL address, while the resource representation is the data obtained when accessed. A resource might be held in a Mongo database or accessed via an URL, but the format of the HTTP response is always JSON, which is the representation of the resource.
Designing RESTful APIs
Designing RESTful APIs is a challenging thing. A good engineer makes the proper decisions of implementation, trade-offs, and naming/explanations of the API. You have to think about your user, who will consume the API.
Understand the business process, participants, and activities. Then, break them into steps and write them down. After that, find the nouns (sometimes the adjectives) in the text.
Create the API definitions and validate them with the key-people involved. I always design the system based on the KISS (Keep it stupid simple) principle and the principle of least surprise.
Consistency is key. Make some decisions and keep ‘em. It will save you a lot of headaches.
Don’t use special characters, underscores, uppercase letters, or trailing slashes.
Use query params for searching/filtering of resources of type collections.
Example: adding items to the cart. In this scenario, we have the items and the cart as the resources. We can then choose the HTTP verbs to manipulate them.
For the URL above, we have a cart of id 34 which can have multiple items in it.
- POST = best fits for adding new items in the cart
- PUT = use this for editing the quantity or property/color of an item that is already in the cart
- DELETE = delete cart items
That’s all for now, next Servers & Node.js.