BT

Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ

Topics

Choose your language

InfoQ Homepage News Reducing Server Load and Network Traffic in REST/Ajax Architectures

Reducing Server Load and Network Traffic in REST/Ajax Architectures

This item in japanese

Bookmarks

It is always enjoyable for me when I find solutions that effectively utilize the simple, foundational tools that our software infrastructure is built on. Instead of building yet more layers of complexity on top of existing layers of complexity, we find ways to solve the problem with the core constructs of the software architecture stack. I think that those moments of serendipity are why architectural styles like RESTful and POJO programming models resonate so much with developers. There is a short article on developerWorks which shows us how to reduce network traffic and server processing for Ajax/REST architectures, but the real jewel here is the way they effectively use the HTTP 304 status code instead of recommending more complicated solutions. The article starts by setting the context for some of the challenges for Ajax/REST architectures:

A simple fact about HTTP is both its greatest strength and its central weakness: HTTP is a stateless protocol. Each request to an HTTP server resource is meant to be idempotent, which is to say the same request should return the same result at each invocation. Idempotency is the central idea in REST: the same request — perhaps encoding client information — should return the same data whenever it is made. ... [But] understanding the meaning of "same data" is more subtle than it might appear. Only in caricature must the same URI always return identical data. After all, even a static Web page might change when the content is corrected (say, the typos are fixed in a published article). The idea behind idempotency is merely that the change involved should not be a direct effect of the GET request itself. So having a constantly changing resource like this is a perfectly reasonable approach:

http://myserver.example.com/latest_data/

The issue is merely that what makes up "latest_data" depends on something other than merely whether, when, and by whom this data has been retrieved. A server can be perfectly RESTful and still reflect "the state of the world."

The problem they are trying to solve, then, is two-fold: reduce network traffic and reduce server processing for repetitive requests. That is certainly not a new problem. The way they go about tackling the server processing part of the problem is predictable: caching. One of the benefits of a RESTful architecture is its ability to be cached. But that only solves the server processing problem; you are still sending the full dataset over the network for every request even if nothing changes. And that is where the HTTP 304 status code comes in:

The "Not Modified" problem is, in fact, addressed right in the HTTP protocol, though this correct solution is underused. What we may — and should — do is simply return an HTTP 304 status code. It is the responsibility of our Ajax code to check for 304 status, and if found, simply not to change client application state based on the (absence of) data sent from the poll.

They were even nice enough to provide some code examples, including what the Javascript making the Ajax call and correctly handling the 304 response would look like:

var r = new XMLHttpRequest();
r.onreadystatechange=function() {
if (r.readyState==4) {
if (r.status==200) { // "OK status"
displayData(r.responseText);
}
else if (r.status==304) {
// "Not Modified": No change to display
}
else {
alertProblem(r);
}
}
}
r.open("GET",'http://myserver.example.com/latest_data/',true)
r.send(null);

Rate this Article

Adoption
Style

Hello stranger!

You need to Register an InfoQ account or or login to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Community comments

  • if-modified-since and eTag support results in real performance gains

    by Randolph Kahle,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Support for if-modified-since and eTags was added to NetKernel in the latest release and this resulted in significant performance improvements for HTTP browser based applications, including the NetKernel management panels.

    As discussed on the 1060 Research forum, the change required only 12 lines of code as it leveraged NetKernel's internal caching mechanism which in turn is grounded on the resource oriented computing abstraction.

    I'd like to see more articles discussing how to take advantage of this on the client side. Is there a list of various RIA toolsets and libraries that take advantage of this approach?

  • Conditional PUT and DELETE

    by Dan Kubb,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    A related, but little known, technique is to use the same approach to perform Conditional PUT and Conditional DELETE.

    Essentially when performing a PUT or DELETE you send the ETag and Last-Modified headers from a previous response as If-Match and If-Unmodified-Since, respectively. On the server side you check to make sure the current resource still matches these conditions, and if it does you execute the method. However if the resource has been modified you return a 412 Precondition Failed status code.

    This allows a form of Optimistic Locking using nothing more than the standard HTTP protocol -- very handy if the resource has been modified since your last request since it prevents you from overwriting the server state using (possibly) stale data.

  • Idempotent? Stateful Client? Cookies? Huh?

    by Gavin Terrill,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    There are a couple of things that I found a little confusing:

    Each request to an HTTP server resource is meant to be idempotent, which is to say the same request should return the same result at each invocation.

    GET, PUT and DELETE requests are idempotent. POST not so much. Idempotent, in the context of HTTP requests at least, means multiple requests have the same effect as a single request. Having the same effect is not the same as having the same result.

    And from the article itself:
    In contrast to the REST philosophy, Ajax applications are often very stateful. Some field or region in a Web application reflects the current state of some server data, with client JavaScript polling used to query that current state periodically

    Showing a representation of the data as it existed when the (RESTful) call to the server was made doesn't make the application stateful per se. To me, one of the biggest advantages of an Ajax app is that it facilitates stateful clients.

    We can track the cached state of the client session by using a client cookie.

    Yes, but wouldn't XMLHttpRequest already be doing that for you?

  • Paging of data sets also helps

    by Mike Pittaro,

    Your message is awaiting moderation. Thank you for participating in the discussion.

    Here at SnapLogic, while we were developing a Dojo data store we realized that
    that the size of responses can also impact server and client side when we're
    dealing with larger data sets. To solve this, we implemented a 'paging' model
    for the outputs of our pipelnes, so a client can request subsets of the data.
    This means we can cache on the server side, and the Dojo data store also
    implements caching by only requesting the required subsets of the data.

    The big benefits are reduced network latency and traffic, plus reduced memory use on the client side.

    We are not supporting eTags and 304 responses yet, but getting that functionality into the Dojo data layer with paging would be a really powerful and easy to use combination.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

BT