InfoQ

News

Reducing Server Load and Network Traffic in REST/Ajax Architectures

Posted by Mark Figley on Nov 20, 2007

Community
Architecture,
SOA
Topics
Javascript ,
REST
Tags
AJAX

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);
if-modified-since and eTag support results in real performance gains by Randolph Kahle Posted Nov 21, 2007 8:55 AM
Conditional PUT and DELETE by Dan Kubb Posted Nov 21, 2007 12:05 PM
Idempotent? Stateful Client? Cookies? Huh? by Gavin Terrill Posted Nov 23, 2007 5:12 PM
Paging of data sets also helps by Mike Pittaro Posted Nov 28, 2007 12:10 PM
  1. 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?

  2. Back to top

    Conditional PUT and DELETE

    Nov 21, 2007 12:05 PM by Dan Kubb

    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.

  3. Back to top

    Idempotent? Stateful Client? Cookies? Huh?

    Nov 23, 2007 5:12 PM by Gavin Terrill

    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?

  4. Back to top

    Paging of data sets also helps

    Nov 28, 2007 12:10 PM by Mike Pittaro

    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.

Educational Content

Brian Marick on 4 Challenges and 5 Guiding Values of Agile Software Development

Brian Marick takes us through a quick tour of the most important values and challenges to adopting Agile successfully (they aren't the typical challenges and values we hear in the community).

Are You a Software Architect?

The line between development and architecture is tricky. Does it exist at all? Is an ivory tower actually needed? There's a balance in the middle, but how do you move from developer to architect?

Agile – A Way of Life and Pragmatic Use of Authority

The word 'authority' sometimes produces an allergic response in hard-line agilists. Freedom and authority – both are bad if misused and both are good if used in right spirit for a noble cause.

Getting Started with Grails, Second Edition

"Getting Started with Grails" brings you up to speed on this modern web framework. Companies as varied as LinkedIn, Wired, and Taco Bell are all using Grails. Are you ready to get started as well?

Using ITIL V3 as a Foundation for SOA Governance

Those familiar with only ITIL V2 often scoff at the thought that ITIL could serve as a governance framework for SOA. With ITIL V3, the focus of the framework shifted towards service-orientation.

Adrian Colyer on AspectJ, tc Server and dm Server

SpringSource CTO Adrian Colyer discusses AspectJ, SpringSource's dm Server and tc Server products, OSGi and Scrum.

Adam Wiggins on Heroku

Heroku's Adam Wiggins talks about Rails, Background Jobs, Add-Ons, Ruby, and how Heroku manages to work around Ruby's inefficiencies using Erlang and other languages.

SOA as an Architectural Pattern: Best Practices in Software Architecture

For Grady Booch the foundation of a good architecture is patterns, SOA being just one of many patterns. In this Second Life presentation, Booch attempts to bring more clarity on what architecture is.