Stateless Architecture : Practical Tips
In a stateless architecture, each request from the client to the server must contain all the information the server needs to fulfill the request. The server does not store any state about the client session on the server side.
Practical Tips for Implementing Stateless Architecture
Utilize HTTP headers for conveying state information. Everything that is not part of the business of that API endpoint should be in request and response headers. For instance, authentication tokens, client metadata, or language preferences can be included in the request headers. Also things like trace ids can be response headers.
Implement token-based authentication (e.g., JWT tokens) to manage user sessions. The token, included in each request header, contains all necessary information to authenticate the request, eliminating the need for server-side session storage. You should also cache the user information to avoid cost if you do not have a token mechanism that does carry information like JWT tokens.
Unless you really have to, like for persisted login feature, do not use cookies in your APIs.
All resources that are used for processing a request should be returned to the system when the request is completed. For example, all threads should be returned to the pool. All outbound requests and all threads spawned from the main thread should have a timeout.
Adhere to RESTful principles to ensure your API is stateless, cacheable, and has a uniform interface. This includes using proper HTTP methods and status codes, and resource-oriented URLs.
A request resulting an error should not impact the system in any way. You have to implement stateless error handling mechanisms and return comprehensive error messages and appropriate HTTP status codes to enable clients to understand and potentially correct their requests.
A request should either be completed successfully and return a 200, or should return an error after an appropriate time has passed. Any other stale states should not be allowed. All stale states should be cleared from the system.
If for some reason, you can not clear stale states immediately or you can not process parallel calls to an endpoint, you should develop mechanism to prevent the clients from making repetitive requests.
Every endpoint that can be idempotent should be idempotent. You should prevent repetitive calls to those that can not.
Provide thorough documentation and client libraries to ensure that API consumers understand how to make requests without maintaining state across calls. This should include examples of request/response cycles and authentication, rules for repetitive requests …etc.
Rigorously test your API to ensure statelessness. This involves testing with multiple clients, parallel requests, and ensuring that the server’s response does not depend on previous interactions.