True RESTful API
Over the past decades, we’ve seen SOAP fall out of favor as the cool kids transition their services over to the REST or GraphQl paradigms, or so it seems on the surface. In 2000, Dr. Roy Fielding proposed Representational State Transfer or simply called REST as an architectural approach to designing web services. Now that the obligatory introduction(?) is done, let's dive into the content. This article is purely focused on explaining six ground principles laid down by Dr. Fielding in order for an API to be RESTful; it has to adhere to the following six constraints.
Stateless means the server does not remember anything about the user who uses the API. Treats every request as new, where no session, no history. Each request sent from a client to a server will contain all the required information to make the server understand the requests sent from the client. This can be either a part of URL, query parameters, body, or even headers. Once your server processes the request, a response is sent to the client through body, status, or headers.
Basically, The client and the server act independently, each on its own. The client-server architecture enables a uniform interface and separates the server from the clients. Advantages are this improves the scalability of the server component and enhance the portability across multiple platforms.
In REST, there are four key interface constraints that we implement to obtain a uniform interface throughout the application,
- Resource identification where the request to the server has to include a resource identifier. We use the URI standard to identify a resource.
- Resource Manipulation using representations where we use the HTTP standard to describe communication.
- Self-descriptive messages where each request to the API contains all the information the server needs to perform the request.
- Hypermedia as the engine of application state. Use hyperlinks and possibly URI templates to decouple the client from the application-specific URI structure.
This is where we say once a developer becomes familiar with one of your APIs, that developer should be able to follow a similar approach for other APIs. Uniformity.
In order to provide a better performance, the applications are often made cacheable. This is the temporary storage of information outside of the server. If the response is defined as cacheable, then the client cache can reuse the response data for equivalent responses in the future. Caching brings performance improvement for the client-side and reduces the load to the server. But there is a downside, the data can be stale, as a solution what we do is refresh the cache, the server decides when to refresh cache data, and the entity managing the cache enforces it.
The layered system architecture allows an application to be more stable by limiting component behavior. Since there could be a caching layer, a load-balancing layer, or other functionality between client and server those layers should not affect the request or the response. This type of architecture helps in enhancing the application’s security as components in each layer only know about the next immediate layer and no more which promotes separation of concerns.
Code on demand
This is an optional constraint and is used the least. The client can request code from the server, and then the response from the server will contain some code or applets to be downloaded and to be used within the application. In essence, it simplifies the clients by creating an application that doesn’t rely on its own code structure.
REST is an architectural style to support API design. Although widely used, there are some drawbacks like lack of state or stateful mechanism and the possibility of a substantial amount of useless data being shuttled around through requests. This was addressed in another API architecture that is GraphQL. This facilitates retrieving the information from an API endpoint in a way that is catered to your query.
However, REST architecture is by far one of the most widely used architectures and its simplicity facilitates rapid development, integration, testing, and deployment.