Are you sure, your APIs are RESTful?
Connectivity is an amazing thing. We all want instant connectivity, that brings anything happening around the globe at our fingertips. But how does that happen?
From desktops, to mobile devices we can Purchase Post Pin and Pick anything anywhere. We are connected like never before.
How does data gets from one place to another? One device to another? How different applications connects with each other?
The answer is Application Programming Interface, a.k.a API. The unsung hero of our programming world. That is the engine under the hood which stay behind the scenes and takes care of every single interactivity we’ve come to expect and rely on it. Simply you can assume an API is an messenger that takes requests and tells a system what you want to do, and gives the response back to you.
What is REST?
A REST API is an RPC (Remote Procedure Calls) mechanism that follows the REST design principles. REST stands for Representational State Transfer.
One obvious question that you may ask at this point is why has REST emerged as a de facto standard when there are so many choices for building Web services or APIs?
There are multiple reasons.
First and foremost is there’s a common set of design principles that all REST APIs must follow. So as a result, the developer of an API doesn’t have to start from scratch. They simply adopt these design principles which make it easy to build APIs. The developer community for APIs has put together proven best practices for building and managing REST APIs.
Second, the REST API can receive and respond with data in any format.
Last but not least, the simplicity of building REST APIs makes it very attractive and there is no standard as such. As a result, REST API developers don’t have to worry about incompatibilities between the client and the server and as there is no standard.
Now, some API developers think that by using HTTP and JSON, they’re creating an application that qualifies as a RESTful architecture, that may or may not be true. Then the obvious question that comes to mind is what makes an architecture RESTful?
And the answer is….
6 Design Rules
In order for the application architecture to be qualified as RESTful, it must follow six design rules. And these six design rules are referred to as the REST architectural constraints.
The first architectural constraint is Client-Server. This constraint states that REST application should have Client-Server architecture. This constraint is the foundation of REST architecture. In this statement, we see two keywood Client And Server, the client is a component that requires the server for resources. One important point to note is, clients and the server should not run in the same process space. Let me explain this in detail.
Traditionally, applications are developed by writing components in terms of modules. So you may write our client module and a server module and then you can package the client and the server module in a single monolithic application which will run as a single process, and then the client module can execute function calls on the server module. So technically this is feasible, but it’s definitely not a good idea as the client component and the server component will be very tightly coupled.
To achieve the highest level or decoupling between the client and the server, the client will make request to the server in some kind of network. This way, the client and server can change independently without impacting each other.
This decoupled architecture leads to something which is known as the separation of concerns. Let me explain it with an example. The client and the server end have a different set of concerns that they need to address and manage.
On the server end there is a need to manage security at multiple levels. Then there is a need to persist the resource data in databases or other storage schemes. Then there is scaling needs as the API load may increase or decrease.
Whereas on the client side there are different set of concerns. For example, how to manage the authentication and authorization for the end user or how to support multiple screen sizes or multi form factors, how to build the application using appropriate technologies and platforms etc.
With this decoupled architectural approach the client and the server can evolve independently.
2. Uniform Interface
The uniform interface constraint states that the client and server share a common technical interface. There are two key words in this statement technical and interface. Interface defines the contract between the client and the server, whereas the key word technical implies that there is no business context for this contract.
There are four guiding principles that are used to define the contract between the client and the server.
- First, the identity of the resource. How individual resources are identified in a request. The REST APIs expose resources and these resources are exposed by way of request URL which are used by the API clients. These requests URLs identify the resource that is going to be manipulated by the api client.
- Second, representation of the resources. The API client receives the representation of the resource. For example, the client may receive data that describes a resource wit it’s attributes and the client can then use the data in the resource representation to carry out the manipulation of the resource. For example, it may use it to edit, show or delete the resource.
- Third, Self-descriptive messages — metadata. The idea here is that the client and server exchange metadata in the request and responses. For example, when the REST client invokes the API endpoint, it can send the information on formats that it can accept in the Accepts header.
- And the fourth principle is hypermedia, which suggest that the server not only sends the response data, but it also sends back hypermedia that the client can use for discovery. Ex. link to edit or view resource details.
This Constraint suggest that the client must manage its own state, thus making the server stateless. Before I talk about the statelessness, let’s look at the design of a typical Web application.
A web application receives requests from numtiple web clients, and when the client first connects to the web application, the web application creates the data structure to manage the state of the client in some kind of a session store. Subsequent calls from the same client leads to the retrieval of the state information of the web application from the sesion store. For every client that is connecting to the web application, the web application manages the state independently. This practice of managing the state in the server is not considered a good practice for building RESTful APIs.
RESTful APIs does not manage the state of the client. Each of the client connecting to the RESTful API server manages its own state. The state management implementation is left to the client application and is not governed or defined by the REST API server. Each client is responsible for managing its own state data.
The benefit of this approach is that it simplifies the implementation of the RESTful API. It allows the API server to easily scale horizontally.
In the previous design rule on statelessness, you’ve read that the API server does not manage the state of the API client. The API client is responsible for managing its own state. This architectural pattern has some challenges.
- First, it can lead to increased chattiness of the application. In other words, the application may have to make multiple calls to the REST of the server to get the resource representation.
- Second, the size of the request data sent by the client to the server will increase as a result of the fact that the client has to send the state data along with the request data.
So the caching constraints suggest that, use of caching to achieve higher scalability and performance of REST applications and server. Caching counterbalances the negative effect of stateless server implementation.
There are multiple points within the architecture which can take advantage of caching.
- The developer of the API may decide to put caching in front of the database. By doing so, the developer can get better performance from the database read perspective.
- Developer can create a local cache within the server to cache the data from the database and also to cache the responses that it’ll send to the REST clients.
- The rest client can also cache the responses locally. This way, the application can avoid making calls to the API server and use the data from the local cache on the application level.
- Between the application and the API server there are various intermediate devices such as proxies and gateways. These proxies and gateways also have caches built into them, and these caches can further improve the performance and reduce the complexity of the client and server from caching prespective.
5. Layered Architecture
A typical 3-tier web application is an example of layered architecture.
There is a Web-tier, then there is an application-tier and then there is the database-tier. Each of these layers have a unique directional dependency on the layer next to it.
So, for example, the Web-tier depends on the App-tier, but the Web-tier is not aware of the database-tier. Similarly, the App-tier has a dependency on the database-tier.
Now let’s say for a specific API, the load on the server has increased to a higher level and there is a need to scale the API. How to do that?
You may add a load balancer, which is a new layer between the Gateway and the REST API server, and then increase the number of servers to carry out horizontal scaling. By this approach, we have added a new layer and we have updated an existing layer. And we did all of this without impacting the REST client because the REST client is dependent only on the Gateway.
One important role to keep in mind regarding the layered architecture is that, a layer can only connect with the layer that it is dependent on. It cannot bypass its dependencies and reach out to other layers.
6. Code on Demand (optional)
Server can extend the functionality of client by sending Code. This is an optional constraint.
So what that means is that, if you have implemented your REST API by following the first five constraints, then your API qualifies as a REST API, even if you haven’t implemented code on demand.
Now, if you think about it, this is similar to how the World Wide Web works. Let me explain what I mean by that.
Now if you think about REST APIs, the only difference is that REST server will send back the response instead of the HTML. This response maybe in different format, depending on the implementation of the REST API. In addition to the response, the API server also sends the code which then gets executed on the REST client, thus extending the functionality of the REST client.
These are the 6 design rules that you can use to transform your API architecture to be RESTful.