Most modern web applications use sessions in some form or another. Sessions are typically used to store information about a client in the interest of improving the user experience: authentication, customized recommendations, shopping carts, and more.
At the same time, many applications are built using RESTful principles. In this tutorial, we’ll take a closer look at what defines a session and whether or not sessions violate the principles of RESTfulness.
2. What Is a Session?
The term session has various meanings in the world of programming. At the lowest levels, it can refer to the TCP connection that controls the connection between two devices.
For applications, a session is simply a way to track state across multiple interactions with the same client. While many modern applications are accessed using HTTP, the protocol itself is stateless. This means applications must implement some form of session management on their own.
Session tracking typically involves assigning each client a unique identifier the first time it makes a request. The client then includes that ID on any subsequent request it sends to the server. On the server-side, the identifier can be used to save and lookup details about that client.
2.1. Typical Uses for Sessions
Session state is difficult to avoid in modern web applications. This is because sessions enable many features that improve the user experience of a website:
- Remembering a user’s logged-in status
- Storing the contents of a shopping cart across multiple devices
- Recalling search filters across different site searches
All of these require the server to store details of prior interactions with the client. And because the client can change (difference device, web browser, etc.) the only consistent place to store this state is on the server.
It’s important to note that sessions are not the same as cookies. Cookies are simply one mechanism for exchanging session information between client and server. But cookies are not the only way, nor are they only used for tracking sessions.
We could also use custom headers, query parameters, or any number of other HTTP features to achieve the same result.
3. REST and State
REST stands for REpresentational State Transfer. It’s an architectural style described by Roy Fielding in his dissertation, in which he described an ideal software architecture for building large, scalable client-server systems.
It’s important to note that in the context of REST, the term state is somewhat overloaded. There are 2 types of state we care about:
- The state of a particular client-server interaction
- The state of resources
When we talk about sessions, we’re usually talking about the former. The state of an interaction between a client and the server is typically what is meant when we talk about session state or sessions.
On the other hand, the state of resources is always maintained by the server. Clients can request different representations, or they can send in modifications to resources. But the server is ultimately responsible for maintaining the resource state.
3.1. The Stateless Constraint
Among the many constraints of RESTful systems is that every request must contain all the required information for the server to fulfill this request. In other words, every request from the client to the server must not rely on knowledge of any prior request.
Specifically, here is what Fielding said about session state in regards to RESTful systems:
Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.
Notice how Fielding makes a distinction here between client state and server state. The server can and should manage the state of resources. For example, the address for an employee or the order history of a user. All of this state is associated with a resource, and ultimately the server is responsible for it.
The client, however, can manage its own state. Clients can store whatever data they deem appropriate, such as usernames and passwords, page history, etc. The key to being stateless is to ensure that every request from the client to the server has all the data needed to fulfill the request.
3.2. The Importance of Statelessness
There are many reasons that Fielding included the stateless constraint when defining REST. First and foremost, stateless systems are much easier to scale.
Consider an application that is deployed to multiple servers. We start multiple instances across different servers, and users access them via a load balancer. If each instance of the application is truly stateless, any client can connect to any instance at any time. This makes the job of the load balancer much easier because it can utilize any available instance when deciding where to send a request. We can also add new instances at any time with relative ease.
However, if each instance maintains a session state for each client it interacts with, then the load balancer cannot simply route any request to any instance. Instead, it must ensure that clients with an established session continue to use the same instance.
This means the load balancer must examine every request and have some understanding of the application itself. Alternatively, we could create some shared context in which every application instance shares its state with all other instances. This is typically done using some distributed cache or data store.
Both of these approaches add complexity to the system. They create new failure points and also create coupling between components that otherwise would not exist.
Aside from scalability, the stateless constraint gives rise to other desirable qualities in an application. For example, we get better visibility into the system because every request can be monitored and observed in isolation.
We also get more reliable systems that are easy to recover. When one instance fails, we simply restart it or add another instance. We do not need to worry about any state that the previous instance was maintaining.
4. Do Sessions Violate RESTfulness?
We’re now ready to answer the question: do sessions violate RESTfulness? Let’s review 2 key pieces of information from earlier:
- Sessions are stored on the server
- RESTful constraints dictate that sessions should only be stored by the client
In this sense, sessions do indeed violate RESTfulness. But that’s not necessarily a bad thing. As with most decisions in software development, we’re making a trade-off.
By sacrificing statelessness, we’re enabling more meaningful user experiences. We can add an item to our cart on our phone, and complete the transaction on our laptop. We can log in to a website once and get a customized view of a page that is tailored to our own filters or settings.
In this article we have looked at what exactly a session is, and whether or not sessions violate RESTfulness. Any session state that is stored on the server violates one of the key principles of REST, that state only be stored by clients.
While this may make our application not RESTful by its original definition, it’s a trade-off that may be worth making. Every application is different and will have varying requirements. By forfeiting some of the constraints of REST, we may be enabling different user experiences.