Please join me at my new location bryankyle.com

Showing posts with label http. Show all posts
Showing posts with label http. Show all posts

Wednesday, March 25, 2009

GET Dirty!

Recently I've been working to design some RESTful APIs and I've come into a situation where it makes sense to update server state in response to a GET method. "What? Change state on a GET!? Are you mad? Are you insane? Have you even read the HTTP spec?" I hear you saying. But just hear me out, it's not as bad as you're thinking.

According to the HTTP 1.1 Specification GET is supposed to be both a safe and idempotent method, meaning that it doesn't have side effects and requesting once or a million times doesn't make any difference. So how is it that I can convince myself that it's OK to change state on a GET? Quite simply, by using a little used (in my experience) status code: 202 Accepted.

The HTTP 1.1 specification has the following to say about 202 Accepted (emphasis mine):

The request has been accepted for processing, but the processing has not been completed. The request might or might not eventually be acted upon, as it might be disallowed when processing actually takes place. There is no facility for re-sending a status code from an asynchronous operation such as this.

The 202 response is intentionally non-committal. Its purpose is to allow a server to accept a request for some other process (perhaps a batch-oriented process that is only run once per day) without requiring that the user agent's connection to the server persist until the process is completed. The entity returned with this response SHOULD include an indication of the request's current status and either a pointer to a status monitor or some estimate of when the user can expect the request to be fulfilled.

In essence, if a POST is made that returns a status code of 202 Accepted the data can be acted upon at some indeterminate time in the future. That time in the future might just so happen to be right before the GET is processed. In this way, the GET is both safe and idempotent since the state change is only tied to the GET in that it's used as a trigger for processing some previously POSTed data.

Sunday, December 14, 2008

Javascript Development Tip #1: no-cache

When doing javascript development that requires files to be loaded from an HTTP server, caching can be a real pain. Turning off browser caching is one solution, but I've always had mixed results. The real solution is to turn off caching on the server side. In order to prevent well behaved browsers from caching your files you simply need to add a header to every response.

The HTTP specification has a list of headers that user-agents and servers should understand, however I've always found the headers around caching to be a bit of a black art. However, for our purposes, there's no magic necessary. To tell the browser not to cache resources, the cache-control header must be set to no-cache. This tells the browser not to cache the resource, not in memory, not in disk, just take the response entity, use it and forget you ever received it.

So, how do you go about adding this header to each response? If you're serving your files from Apache, you can use mod_headers. mod_header allows you to add arbitrary headers to responses. The module has a lot of capabilities, but only the basics are required for our purposes.

The first step is to enable the module by adding a line similar to the following to your httpd.conf. Most installations of Apache have this line conmmented out. If that's the case, just uncomment it.

LoadModule headers_module modules/mod_headers.so

With the module enabled, you can have to modify the headers of outgoing responses. If can be configured server-wide, within a virtual host, a directory using .htaccess. You can also enable it in <Directory>, <Location>, and <Files> sections. Whichever you choose, just add the following line, save your changes and restart the server.

Header set cache-control "no-cache"

This tells mod_headers to set the cache-control header to no-cache for all responses within its configured scope. If the cache-control header has already been set, it will be overriden by the value you've specified.

To verify that the configuration worked, clear your browsers cache and make a request to one of the resources covered by the configuration of mod_headers. If you're using Firefox and have Firebug installed, you can switch to the Net tab and look at the response headers.

So there you have it, an easy way to speed up development and reduce your stress by simply removing caching, the real way.