Primitives only in session

HTTP is stateless and cookies make it stateful. The most important cookie of all is the session id using which the web server frameworks remember a user. Most interesting web applications ends up with a cluster of web servers instead of just one. One strategy for handling user sessions seamlessly across nodes is to have a persistent store where the user session information is stored, as in the ones provided as, like ASP State or Tomcat's persistent manager. These details are abstracted from the session user (developer) to allow for flexibility at runtime via simple configuration changes.

These sessions in web-framework managed also allow objects as long as they are serializable. This is quite convenient and feels natural to object people, as it allows to structure the session data. But this can lead to some unwanted consequences under the covers of abstraction, surprise!. The worst thing is that most of us learn it the difficult way by witnessing it happen the production. There are three important issues one need to be aware of:

1. Session object state changes are opaque to session implementation

To understand this scenario lets understand the reality from session implementation point of view. The web frameworks provide us an instance of session object, which is of type interface, on which we operate. The real class doing the hard work is what I refer here as session implementation. When we want to change a primitive value in session we write a new value against the same session key. Since objects unlike primitives are mutable we can change the session information by loading an object and changing the object, without having to overwrite the session key value. Here in lies the problem for session implementer since it has to assume that any object read from session might have changed, hence should be kept as is. Now, this is a non-issue when session is backed by memory. But when session is backed by persistent store, the implementation has to persist all objects which were accessed during the request. This unnecessary save in large scale can cause performance and resource utilization issues.

{{Code sample showing get object from session, change data without writing to session}}

2. Risk of unwanted data ending up in session payload

The objects we store session might be used in other parts of the code base. For example, good object programmers might also want to put logic in such classes, following tell don't principle. While this doesn't hurt but it takes you one step closer to one where one also puts reference to the dependants in the same class. This is undesirable when session is backed by persistent store as now such objects might also get stored. While I have taken one example, the fact that the object one is using is also an object saved in session is not obvious in all places. This leads the mistakes which can be very costly.

{{Code sample showing an object used out of context of session and new field added to it}}

3. Memory backed session store doesn't mandate serializable objects

This is an irritant since you would be using persistent session store in production (and hence in test environments). This delays finding of such issues if developer for simplicity purposes has set up one's development machine with the memory backed session store.

Session backed objects

These let you have the best of both worlds, allowing you to deal with objects but ensuring that you are not saving them in session. These objects look like:

{{Code sample}}

This style makes it very clear that the object is meant to be used for session storage. The other important aspect of this implementation is that we are not using the session object directly but rather our own wrapper which allows only primitives to be stored. While this doesn't enforce the direct use of session, but it is effective in avoiding costly mistakes.