REST (Representational State Transfer) is an architecture style for designing and developing loosely coupled web services. It does not enforce any rule regarding how it should be implemented at a lower level, it just put high-level design guidelines and leaves you to think of your own implementation.
The following are the architectural constraints to make web service a pure RESTful service:
1. Uniform Interface
REST architectural style focuses on defining the uniform interface between the components simplifying the overall architectural style and giving improved visibility of their interactions. This allows components of the network system to evolve independently.
Roy Fielding defines four interface constraints as identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.
This constraint is derived from the principle of separation of concerns and essentially means that client application and server application MUST be able to evolve separately without any dependency on each other. Servers and clients can be replaced and developed independently, as long as the interface between them is not altered.
Server being stateless basically means it will not store anything about any HTTP requests made to the server by the client. With this constraint, we should make all client-server interaction stateless so that each and every request to the server will be treated as new request.
The client end is responsible for maintaining the session if client application needs to be a stateful application for the end user.
This constraint mainly focuses on improving the scalability and performance of the system by caching the response from the server. Server should label, implicitly or explicitly, the data within a response to a request as cacheable or non-cacheable and if a response is cacheable, then a client cache can reuse that response data for subsequent equivalent requests. However, caching can be done on the server side as well.
5. Layered System
RESTful services can be composed up of a layered system where one layer is unaware of another layer it is interacting with. Layers can be used to encapsulate legacy services and to protect new services from legacy clients, simplifying components by moving infrequently used functionality to a shared intermediary. Intermediaries can also be used to improve system scalability by enabling load balancing of services across multiple networks and processors.
This leads to a microservice architecture where the client cannot ordinarily tell whether it is connected directly to the end server, or to an intermediary along the way. For example, the incoming requests from the client to API A can be authenticated on Server B and forwarded via gateway C.