Pete Hodgson

Software Delivery Consultant

REST: 'There aren't enough verbs'

April 19, 2009

I think one of the more frequent issues that people have when starting to work with a RESTful architecture is that "there aren't enough verbs".

Why having few verbs is good

When we look at the big picture we see that this paucity of verbs is in fact one of the strengths of REST. A small, standard set of verbs allows all parties to agree (in the most part) on what the semantics of those verbs are. This in turn allows the creation of a lot of loosely coupled infrastructure which any REST system can take advantage of. An obvious example is the sophisticated caching system within the world wide web. All parties can agree on what a GET means, specifically that it's an idempotent operation. That allows intermediaries to know when a response is cachable. If each application was creating its own set of verbs we'd no longer be able to leverage all this 'free' infrastructure which has built up. If a cache somewhere between your user's browser and your data center doesn't understand what the semantics of some custom verb are then it can't safely cache your responses. Same goes for your user's browser. This is one of the reasons why RESTful folks don't like web services with RPC-style architectures. By tunnelling everything through POST and a single URI these services lose the ability to confer semantics to intermediaries. These kinds of services are on the web, but not of the web.

What to do when you 'need' more verbs

So, we are agreed that a small, standard set of verbs is a good thing. What then is an API designer to do when modeling a complex operation which doesn't map nicely onto that small set? In my experience there are generally two solutions. We can use an overloaded POST, or we can add some additional 'activity resources' to the resource space of the API. I tend to prefer the latter, but I think it's important to not be dogmatic about this. There are certainly situations where an overloaded POST is the way to go.

Let's discuss what I mean by 'activity resources'. Generally when people start designing the resource space for their RESTful API they might write a description of what functionality the API seeks to expose, and then go through the text underlining nouns. If this is reminding you of an analysis technique for a certain other paradigm then stick with me, I'll be coming back to that in the next section. This set of nouns would generally be a good starting point for identifying resources. I'll call these types of resources Entity Resources. Let's say we're working on a hotel reservation system. After this initial stage of analysis we might come up with a set of entity resources such as Guest, Room, Hotel, Bill, etc. We'd probably also have Reservation in there too, but I wouldn't classify that one as an entity. So far so good. Now, let's say we're working on the checkout part of the system, in particular on credit card processing. We need a way to represent the act of a Guest paying their Bill with a credit card, having that credit card transaction approved or declined, etc. A lot of developers (particularly those coming from an RPC mindset) will want to do something like add a PAY verb to the Bill resource. This makes sense. Paying is an action that is applied to the Bill. It makes sense, but as we've discussed above REST frowns upon extending our small set of verbs. So instead we can create an Activity Resource called Payment. This resource can contain a reference (in the form of a uri) to the Bill it is a Payment for, along with details like credit card number, etc. In addition we can add a Payments resource which belongs to each Bill. When a customer wants to pay a bill they can send a POST to the Payments resource, supplying a representation of the payment they want to make. That POST will create a Payment resource representing the transaction, and supply the user with a uri for that resource in the form of a redirect. The customer can GET on that resource to check on the state of the payment transaction (Processing,Successful,Denied), etc. Maybe if the payment was denied they could PUT to the resource with a corrected credit card number. The key pattern here was to take an action (paying a bill), and to model that as a transitory Activity resource. Adding that extra level allows us to model the behavior in a RESTful way. I've frequently seen transactions modeled RESTfully in this way.

Sidebar: Parallels in grokking REST and grokking OO

When I was going through the slow, laborious process of getting these ideas into my thick skull I experienced a vague feeling of déjà vu. I eventually realized that this was just like when I first started to really grok object-oriented design. Often when students are being taught to design object oriented systems a suggested technique is to write a description of the business domain and then underline the nouns in the description. These nouns will be the classes in your system. However, after gaining experience with OO I think most developers realize that these classes are not where the meat of a design lies. The meat lies in the interaction between these entities, how they are composed and how they interact. Using polymorphism and composition to create clean, loosely-coupled systems becomes much more interesting than designing the Is-A inheritance heirarchies that often appear in introductions to OO. And here lies the parallel with learning RESTful design, and my sense of déjà vu. When learning REST the core concepts of Resources, Actions, Uris, etc. are necessarily explained first, and most pedagogical examples focus on simple systems consisting of what I referred to above as Entity Resources. However when you start to do real work with a RESTful architecture you start realizing that large parts of the system are about modeling the relations and interactions between these Entity Resources. I expect that as we gain more experience with the REST style then the common problems and shared solutions will start to emerge, in the same way as we saw OO design mature in the 80s and 90s.