users@jersey.java.net

Re: [Jersey] Web applications using XMLHttpRequest and JAX-RS REST/JSON Web Services

From: Craig McClanahan <Craig.McClanahan_at_Sun.COM>
Date: Fri, 07 Nov 2008 00:11:19 -0800

Craig McClanahan wrote:
> Eduardo Pérez Ureta wrote:
>> Ideally I would like to use the servlet session.
I should have responded to this particular statement in my previous
response (sorry for the omission). And it relates to some comments I
*did* make that might not make a lot of sense without a little bit of
context.

One of the key principles behind RESTful APIs is that they should be
*stateless*. In other words, if the server is implemented as multiple
instances of your application behind a load balancer, it should not
matter if the (n)th request and the (n+1)th request are served by
different instances. This is a key attribute in designing an
application that can scale beyond a single server instance.

When you use servlet sessions, you are risking a violation of this basic
principle. Let's assume that you are taking the typical approach where
a cookie is used to tell the client what session identifier to submit on
subsequent requests. The usual server side implementation of a
"session" is essentially a HashMap of session attributes, keyed by the
session id. But the *crucial* point is that this information normally
lives only within the context of a single JVM (i.e. a single instance of
your server). Supporting an application that scales horizontally (that
is, across multiple server instances) would require that either:

* the load balancer recognize that a subsequent request belongs to an
  existing session on a *single* instance of your application, which means
  you are likely to experience service overloads if this single instance has
  too many active sessions. (You will often see this referred to as "sticky
  sessions").

* the server environment recognizes that there is an existing session, but
  the data for it lives on some other server instance so it needs to be
copied
  to this instance before the request can be processed. As you can imagine,
  there can be significant overhead in doing this sort of thing.

With respect to authentication (which was the particular context of
Eduardo's questions), the standard HTTP approach is to include an HTTP
header named "Authorization" with each request -- most typically using
the HTTP Basic authentication scheme
(http://www.ietf.org/rfc/rfc2617.txt). This means that the
authentication operation must occur on *every* request, but it also
means that you can indeed scale your application across multiple server
instances, because any one of them is capable of performing the
authentication transaction. You would be wise, if you are planning on
an application that does, or even *might*, require deployment of more
than one instance, to keep this consideration in mind.

For a Java developer who doesn't want to care about all the nuances and
complexities of the HTTP protocol, my recommendation is pretty simple --
figure out how to design your application without using sessions. For
authentication, that's pretty simple ... just include the authorization
header on each request (for human-interaction web applications, browsers
even do this for you if your server is designed for HTTP Basic
authentication). For application state, everything that the server
needs to know about the current state should be included with each
request. (The details of this topic is the source of many thesis-length
dissertations, but the fundamental principle is pretty easy to grok.)

Or, of course, if you *know* your application will never need more than
one instance (even to ensure availability in the case of an instance
failure), you can safely ignore this advice. But can you really be
sure? (For a 10-user departmental app behind your company firewall,
sure you can. For an Internet facing app, no way IMHO. All it takes is
a single "Slashdot Effect" surge of interest in your app, which
overloads your single server instance, to demonstrate to you (and to the
world, unfortunately) that you weren't ready for Internet scale user
traffic).

Craig