Skip to main content

What REST is NOT

Update: I spoke with the president of Gigya.

Having only familiarized myself with REST a few months ago, I still struggle to explain to colleagues what REST is. My best one sentence summary so far is that it's "using HTTP as it was designed". Not a perfect or even complete summary, but I think it covers the highlights.

This week I've been reviewing Gigya's REST APIs for an upcoming project at work. And I've found it to be a shining example of designing an API incorrectly and calling it RESTful. It solidified a couple of REST anti-patterns for me and I wanted to capture them:
  1. REST is not RPC, though RPC can be done RESTfully.
  2. GET is not for state changes. If you're operation has side effects, don't use GET.
  3. The response body is not the only way to send the client information. Don't duplicate information in the HTTP headers in the response body.
  4. Authentication is not part of your resource. Don't create a query parameter to do authentication, use the HTTP header that already exists for the purpose.
REST is not RPC
Many developers coming from a SOAP background think RPC calls can be ported to 'REST' and then call it a day. They are missing a big mental shift in the way to think of web services when designing using REST principles. Instead of thinking of services as functions that can be called, change your thinking to performing operations on objects, formally known as 'resources' in REST parlance. The operations you can perform on your resource are the existing HTTP methods, GET, POST, PUT, DELETE, OPTIONS and HEAD. So instead of exposing a 'setStatus' function via a web service, instead expose a 'status' resource that can be POSTed or PUT to change it, call GET to retrieve the current status, or DELETE it to clear the status. REST is not functional RPC, its a paradigm shift to treating web services in an object-oriented way.

GET is not for state changes
The most important REST principle that Gigya's APIs violate is using GET calls to affect the state of a resource. Short of recording access, like last viewed by/on, GET calls should never affect the state of the resource it represents. If you need to change a resource, there are three other HTTP methods for that purpose, namely POST, PUT and DELETE. The use cases for DELETE are pretty self-apparent, but I've got to admit to being confused of when I should choose POST vs. PUT. John Calcote clarified the answer nicely of when to choose POST over PUT.

The response body is not the only way to send the client information
HTTP headers, for both requests and responses, can be an invaluable way to simplify your API. They can contain rich information about the success (200 OK, 201 Created, 204 No Content) and failure (404 Not Found, 401 Not Authorized, 503 Service Unavailable) of a request. Gigya for example includes the HTTP status code in their XML response body. It seems like a waste of bandwidth to me, when the status code is already included in the response headers. To their credit their documentation seems to imply the codes are more detailed than available in the HTTP spec (500-001, etc) but their examples conflict with that and only show the XML return simple HTTP codes with HTTP reason messages. Even if they provide more detailed information, it should not duplicate what already exists in the request. Trust that your API users can understand and use the headers. Its much easier to only check a status code instead of parsing an XML response.

Authentication is not part of your resource
This antipattern is directly related to my last point of using HTTP headers properly but its important enough to warrant its own bullet. This violation is a version of "don't reinvent the wheel". Gigya has for some strange reason taken OAuth and permuted its use rather than sticking to the spec. They even have API users sign their requests using OAuth libraries but then fail to carry that through into the API usage. The signature a part of the GET query string rather than use the already established HTTP header that the OAuth spec has defined for carrying that data point.

Summary
REST is a very amorphous set of principles but that doesn't mean there are no concrete guidelines. Patterns are emerging as well as anti-patterns and Gigya has examples of both. I don't mean to pick on Gigya but they just happened to be freshest examples in my mind this week. The big points I'd like you to take away from this are, don't reinvent the wheel, use the existing HTTP methods properly, don't forget that HTTP headers exist and design your APIs by thinking of them as objects rather than functions.

Comments

Joe said…
Something that really helped cluck that switch for me: think nouns (addressable resources) not verbs when dealing with abstractions and REST API

-joe
Thanks Joe, that's exactly what I was trying to get at with my 'REST is not RPC' point. Well said.

Popular posts from this blog

TeamCity build triggering by GitHub

So I started using GitHub for a side project and discovered their very cool feature of service hooks. A service hook allows a repository administrator to setup a callback to another service when a commit is made to the repository. For example it can send an email, or chat a message via Jabber.

Now continuous integration servers, like TeamCity, can poll source control systems every few minutes to see if any changes have been committed. But wouldn't it be more efficient to use a service hook to trigger a build?
Looking at GitHub's service hooks, there wasn't one already available to callback a TeamCity server, but right on that same page was a link to the open source repository for GitHub Service Hooks. They "eat their own dogfood" so to speak and make it very easy to contribute new service hooks back to them. So I took an evening, did my first Ruby coding in a while which included more time getting Ruby setup and working on my Macbook than actually coding. In a …

Paperless

I've been slowly going paperless over the past decade. The first step on my journey started in 2000 when I signed up to use a payment service, PayTrust, to receive my incoming bills, scan them, and put them online for me to pay. The next major step was probably when I got a digital camera to replace my traditional film cameras. It might not be considered a "paperless" use case, but it has lead to very little hardcopies over the years as monitors and HDTV with screensavers and AppleTVs have become so beautiful.  Back to the paperless office, my next big step was eFileing my taxes but that didn't come until about 5 years later. Then suddenly about two years ago, I hit a real shift in my desire to go completely paperless when I got my iPad and installed Evernote.

digital notes...
If you aren't familiar with Evernote its an excellent app, available on all the major desktop and mobile OSes, that makes note-taking and organizing really simple. The killer feature is …

My Journey to Fitness, a 5K, and my first Triathlon

My name is Brian and Sunday I became a triathlete. My journey started ten months ago when I decided to get back into shape after 15 years of being obese and out-of-shape with some yo-yo dieting in the middle. What changed? I'll get to that.
This weekend I competed in the first ever Rocketman Florida Triathlon which took place on the grounds of Kennedy Space Center at Cape Canaveral. In preparation I lost 50 lbs and 12 inches from my waist. But I'm getting ahead of myself.
I'm a huge space buff. As a kid I wanted to become an astronaut. I went to Space Camp in Titusville when I was 10. Before that, I saw my first shuttle launch at 7 while on vacation. It was the final launch of the Challenger. I've written about that experience. I've seen three other launches since then including John Glenn's famous return to space as well as the final launch that ended the U.S. Shuttle Program.
The idea of biking on the restricted grounds and getting closer than any civilian h…