this is totally gonna work… » REST

How To Make URLs

October 26th, 2007

One of the things that makes a web application “look” RESTful is the type of URLs it presents. Like many things, whether or not these URLs really meet a particular criteria is a matter of degrees. But anyone who has some basic understanding of a resource-oriented view versus a functional view can tell the extremes apart (e.g. /system?sport=football&team=seahawks&year=2006 vs. /football/seattle_seahawks/2006).

However it’s the in-between URLs that seem to provoke the most heated discussions between the REST-anistas and the non-believers. Those not impressed with REST would argue that all we’re doing is prettying-up our URLs with no real functional improvement. Now I happen to prefer good-looking URLs over ugly ones because I think they are easier to work with. But outside of the aesthetic argument I couldn’t really make a good case for RESTful URL design. However, after a bit of thought, I’ve come up with a theory on how URLs ought to be constructed.

The Theory

Requests for resources have two basic components: the identity of the resource and variation information. Identity is the minimum amount of information required to distinguish one resource from another. Variation criteria is additional information that refines or qualifies the representation of the requested resource. Variation information can include things like:

  • type of requester
  • content type
  • session or user
  • portions of the representation

In a proper URL design, identity information should be expressed as a first-class notion. In URLs this is best expressed within the path portion of the URL. This information does not belong in request parameters. This not only makes your URL structure easier to manage mentally, it also stands a better chance of working well with HTTP caches (more on this in a bit) and proxies. Variation information can be expressed by the requester in any combination of headers (e.g. Content-Type) or request parameters.

Hold the query parameters!!!

So why do so many people fall back on request parameters? In the Java world, I think a lot of it comes from people developing applications in a Servlet environment. The servlet specification provides no easy way to access path information. You have to get the request path and split the string by hand. Yecchh. Also, the built-in URL mapping in Servlets leaves quite a bit to be desired. So a lot of folks just fall back on the simple dictionary interface that servlets provide for request parameters. Unfortunately this has bred a lot of bad habits in Java web developers.

I think the other reason this design is prevalent, is the holdover of the first great paradigm shift on the web when we moved from “web sites” to “web applications”. Many of the people writing the first web applications (myself included) tended to view HTTP requests as function or method calls where variable information is passed in as arguments. What many of us failed to realize was that requests for dynamic content didn’t require a different way of structuring URLs. We were still, by and large, asking for things.

There are two problems with the functional approach. The first is that a lot of request parameter information could be better expressed with existing headers. The second is action-oriented view that developers take of these requests which violates a core principle of REST where a finite set of actions are applicable over an infinite set of nouns.

Collections

One place where query parameters make sense are specifying views across collections. This is also known as providing a search parameter. Think of the Most Popular URL In The World, http://www.google.com/q?=. When you search, that ‘q’ parameter is a specification for a filtered view of that top-level Google resource. In other words when you query for http://www.google.com/q?=Led+Zeppelin you’re really asking for all things Led Zeppelin from the Google collection.

On a smaller scale, query parameters are quite appropriate when asking for a filtered view over a collection that has arbitrary dimensions. However, not all views over a collection should use query parameters. For example, in a case like Flickr where tags are first-class aspects of certain resources, /tags/ is expressed as a path segment. When resources are normalized like this, you should favor paths over query parameters. However when you want to select a sub-set of resources out of some larger heap and the way you specify that subset is open-ended, query parameters are a good way to go.

Caching

Perhaps the best rationale I can give you for the RESTful approach is that playing by these rules will allow you to take full advantage of HTTPs built-in caching semantics. When you think about what a cache has to do and all of the rules it has to follow, its main function is identifying and returning cached responses to cacheable requests.

That Wild West Frontier that is the “query parameters” section of a URL can give HTTP caches fits. Heck, by default Squid ignores query parameters for resource identification. You have to go out of your way to get this to work. You could argue that Squid “isn’t doing it right”, but I think it would be more fair to say that Squid is trying to be safe with regard to query parameters. This is similar to the way Google’s Web Accelerator treats URLs with query parameters (i.e. an opaque Pandora’s Box not to be trifled with.)

So keep your URLs clean! Figure out what information you need identify a resource and keep it in the path of the URL. Use headers or request parameters for any of the variation information.

Why Can’t Web Apps Be REST-ful?

June 26th, 2007

In case the recent posts haven’t made it obvious, I’ve been on a bit of a tear about REST lately. In large part this is due to Leonard Richardson’s and Sam Ruby’s “RESTful Web Services” book that I picked up at RailsConf. One of the thoughts that has been bouncing around in my head is how web service-oriented the book was and, besides a chapter about Ajax, said very little about how REST applied to user-facing web applications.

I wondered to myself, “are browsers so broken that we can’t make REST-ful web applications?” I know that in the last year there have been times that I have really struggled with applying REST consistently to web applications. Things like the sign-up and sign-in process seem like square pegs trying to go into round holes. Should I have just given up on REST?

Before we can answer this question we first have to tackle the sticky question of just what, in practice, makes a web app REST-ful or not. One of the obvious places to start is the URLs of your application. It feels pretty un-RESTful to have URLs like /signup or /signin since these are very verb-oriented—REST prefers an infinite array of nouns with a very constrained set of verbs.

So how do URLs like /signup and /signin become REST-ful? One possibility is looking at what the underlying nouns are for these actions. The act of “signing up” for an account could be modeled as POSTing user information to a noun like /accounts—the resource we are attempting to create with the POST message is an account. Similarly, the act of “signing in” is really the act of creating some authorization within an application. We could POST our credentials to a resource like /sessions or /credentials to create an internal resource representing our session with the site. Now things get a little sticky when strictly adhering to REST-ful guidelines and trying to do authentication. That’s a whole other topic for a different post at a different time. Let’s say that with a little thought, you can create REST-ful URLs that still work quite well within a web application.

The next thing to consider is one of the biggest places where strict adherence to REST falls down: the lack of support for any HTTP verbs beyond GET and POST within (X)HTML. Frankly it’s just shocking that we are in this predicament. I really hope that there’s either a good rationale or funny story for why things are this way. I really really hope that it gets fixed soon. Currently there are two ways around this: Ajax and the “_method” parameter hack a la Rails.

The first technique is reviewed in Richardson and Ruby’s book. It turns out that Ajax-driven applications fit pretty nicely with REST. Other than Safari/Konqueror, browsers can support other HTTP verbs quite easily with XMLHttpRequest. Because the Ajax client code shoulders the bulk of the responsibility for the UI, the backend resources can limit their returned representations to data that the Ajax clients work with. This gets rid of a lot of sticky problems that come with having to render fully-functional pages with each request.

The second technique is essentially a hack, but one that allows to code our resources REST-fully. Frameworks like Rails and Restlet do this for us automatically. Even if you are using another framework or rolling your own, you should be able to apply this little “hack” in a nice little corner of the request-response dispatching code without too much fuss. In short, I’m willing to live with this little turd to keep the rest of my system consistently organized.

OK, we’ve got our nouns squared away with a consistent set of verbs. Well-factored nouns implies a good URI design (how else will we identify resources?) What else do we need to have in place to be REST-ful? Hmmm, how about proper state responsibility? You will often hear people say that REST-ful applications are stateless. I think this misses the point. The HTTP protocol is stateless, but your applications undoubtedly have state. Any app with a shopping cart has state. So the question then becomes, do user-facing web applications have different needs that necessitate a violation of REST regarding state?

The short answer is probably not. By and large your application state is usually server-driven and ideally done via “hypermedia as the engine of application state”. In practice this means that the current state of a user’s shopping cart is probably persisted in a shared store allowing any application node to serve the client’s request. Yes folks, a good bit of why REST guys harp on statelessness is for the sake of scalability.

Things get a little grayer when we want to have small bits of saved state on the client for things like “remember me” features or other quick, token-based identification schemes. I won’t lie to you, I’ve used cookies a lot. I know the strict REST approach decries their use and characterizes them as the root of all internet evil, but if they weren’t so damn useful I’d be in complete agreement. Like real-life, having cookies often is probably not a good thing, but once in a while isn’t going to do any long-term damage.

So, can user-facing web applications be REST-ful? Sure. Are there some compromises to be made along the way? Most likely. Does that mean that REST is an overly-idealistic approach that fails in real-world implementations? I would say not—however, your mileage may vary.

Posted in REST | No Comments »

Book Review: RESTful Web Services

June 22nd, 2007

Leonard Richardson & Sam Ruby

I picked this book up from the Powell’s booth while at RailsConf 2007. I had been following the online manuscript for a while and as soon as I saw that the book was in print I snapped it right up. I wasn’t the only one either. REST was a very hot topic at RailsConf and I saw a lot of other attendees with a copy under their arm.

I’ve been keenly interested in REST for about the last year and a half. I’ve read

Fielding’s dissertation a couple of times and read some good blogs, but really felt like REST was missing a more accessible, canonical resource. After completing this book, I think I’ve finally found one.

The author’s do an excellent job of distilling the principles of REST and describe an imlementation of it they term Resource-Oriented Architecture (ROA) which has specific recommendations. I’m pretty sure that my copy will be referred to time and again and that I will probably eventually re-read its contents. I only wish the authors had done more to address using REST in human-facing web applications, not just web services.

4 out 5 stars.

Why REST Matters

June 12th, 2007

I first ran across REST in my reading about a year and a half ago. While it took me some time to “get” what REST was, I quickly became a fan. However I’ve found that aside from pure aesthetics, I’ve had a hard time articulating why REST is not only beautiful, but effective. I’ve spent a little more time thinking about REST and I think I may have a couple of concrete arguments for REST that go beyond a simple appreciation of its beauty.

uniform interface

Uniformity of Interface

When resources present a uniform interface, we can take advantage of this simplifying assumption. We can focus more on what we can do with resource rather than how we interact with them. This simple convention takes a lot of churn out of the development and integration process.

Uniformity also constrains system design to the minimum required for distributed computing. Anything else is simply baroque elaboration that provides little to no value (think of SOAP’s SOAPAction directive) and is nearly always at the cost of the uniformity.

works with httpWorks with HTTP

Assuming that you are going to provide data via the web, you are working within the constraints of HTTP. Since HTTP is an expression of the principles of REST, it is both foolish and counter-productive to go against the grain of HTTP’s architecture. Unfortunately, HTTP is a very misunderstood protocol. It is sad that so few people who develop with HTTP understand it so very little.

One of the least understood parts of HTTP are its caching mechanisms. Not only is caching misunderstood, it is terribly under-utilized. Most developers simply know caching as something to disable at all costs. This reflects an abuse of the protocol and an unnecessary effort expended to go against the grain.

When you express your resources as distinct URLs, you can take advantage of the built-in caching semantics HTTP provides. A large reason (though not the only reason) that many web developers work so hard to turn off caching is because their applications are verb-oriented and tend to operate through one or a few separate URLs.

Similarly, the semantics of content negotiation are also rarely well-understood let alone used in the wild. HTTP’s content negotiation mechanism separates the concerns of what an underlying resource is from how it will be represented. This is a good separation of concerns—a user’s account details are a user’s account details regardless whether they are displayed in HTML, JSON or XML.

Connectivity

connectivity

Connectivity is the way a web application connects within itself. One of Roy Fielding’s main assertions is that REST uses “hypermedia as the levers of application state”. This is achieved by the linked hypermedia returned by a resource. Connectivity provides further simplifying assumptions about how a site is connected. Instead of relying on complicated specifications like WSDL, consumers of REST-ful applications can use a lot more of a web application based simple guidelines.

The Design Analogy

design

Let’s try to put resources in terms of object-oriented design. A classic symptom of poor object design is where the functional aspects of the system are the first-class attributes of the system and any “objects” are simply data structures passed from function to function. Good object-oriented design puts the behavior right next to the data with a healthy sprinkling of encapsulation.

You wouldn’t have a single function that took an arbitrary number of parameters that could return an arbitrary type or amount of data or perform an arbitrary functions. The complexity would spiral out of control quickly and you would want to create some kind of taxonomy. In object-oriented design these emerge as objects that describe distinct domain entities. Why shouldn’t this apply to web applications and services?

Your Checklist for Winning REST Arguments Around the Watercooler

So let’s sum this up into something you can print out, cut down to pocket-size and laminate and keep in your wallet:
- REST is about resources. There are an infinite number of these, but a very finite number of things you can do with them.
- This simplifying assumption makes client consumption of data simpler.
- This simplifying assumption makes for cleaner resource design.
- Since you’re using HTTP, you might as well use it correctly. Read the spec!
- REST promotes connectivity. Express the connections between your resources and make your application more discoverable and navigable.
- REST prefers a separation of an abstract resource from its physical representation. This is good design.

Posted in REST | 9 Comments »