Blog Archives

HTTP Status Codes and RESTful API crafting

Posted in Agile Development, Code, Inside TFG, Ruby on Rails, Tips and Tricks

These days there’s a lot of money in mobile applications – and where there’s money and new technologies there’s web developers primed and ready to argue about how best to implement these new technologies.

As one of this dedicated crowd I’ve found myself recently working with a lot of Rails RESTful APIs that talk to my mobile applications. This has given me the opportunity to both create my own RESTful APIs and use RESTful APIs written by other developers.

As a result, I’ve gained a much better understanding of the HTTP Status Codes and how they can help you write both better APIs and client applications.

For clarity, I use the term ‘client’ to refer to the mobile application that is communicating with the Rails RESTful API backend.

When I say API I’m referring to a Rails RESTful API.

Before I begin, here are some good sites for reading up on the HTTP Status Codes:

  1. ietf.org (Internet Engineering Task Force) RFC2616
  2. w3.org RFC2616
  3. httpstatus.es
  4. Wikipedia List of HTTP Status Codes
  5. REST Patterns HTTP Status Codes

Here’s a good article by Alex Rogriguez over at IBM from 2008 on REST APIs. If you aren’t clear on what a RESTful API actually is give Alex’s article a read.

Here’s an example on how Twitter handles HTTP Status Codes and a RESTful API

For more examples you can do a quick Google Search and you’ll find the REST API docs from Microsoft and Dropbox, among others.

Finally, for the super-keen, here’s a list of the stackoverflow questions on ‘rest’ and ‘api’ sorted by votes.

Now, back on point!

Why are Status Codes important?

The status code works hand-in-hand with the response body to help the client application process the request.

Status codes tell the client application what it needs to do with the response in general terms.

For example, if your API returns a 401 you know you need a logged in user. If the API returns a 403 you know the user you’re working with doesn’t have sufficient authorization. If the API returns a 418 you know that the API is telling you it’s a teapot and was probably written by knobs.

The response body will tell your client application in specifics what it needs to do with the response. If the client is trying to update a record and the API responds with a 400, the response body will inform the client why the request failed. On the other hand, if the API responds with a 200 the response body will provide the client with the updated entity.

That seems pretty straight forward, right? The difficulty lies in when the API returns a status code and a response body that don’t match up.

I worked with an API that returned a 200 status code but the response body had an errors array in it. That was an absolute trip – I had to parse the response body and look for the presence of content in an errors array first. Then I called an error handler from within the success callback of a jQuery ajax function. This is an example of a bad RESTful API. I hope by reading the remainder of this article you can avoid doing that.

Which status codes should I be using?

As long as you’re not too pedantic status codes are easy to work with when writing an API.

Here’s a rough guide to how I handle mine:

(For the purpose of all of the examples below, any response content I refer to will be as JSON.)

(2xx) Success Codes

200 OK

The 200 OK status code can be your go-to for any successful response. There are many success codes but for a very basic API I’ve found the 200 *can* be expressive enough. The distinction between 200 and the other success codes hasn’t proved valuable in my APIs so far.

See the IETF docs on the 200 status code.

However, some other Success Codes you might be interested in:

  1. 201 Created for when you’re creating a new resource.
  2. 202 Accepted for when you’ve successfully set the request to be performed in a background task. Useful if your client is requesting something on the API that is time-consuming and you don’t want the client to have to wait.

What should I return in the 200 response content?

The content of the response is dependent on the HTTP Method used in the request.

Quoting from the IETF RFC2616 docs:

GET an entity corresponding to the requested resource is sent in the response;
POST an entity describing or containing the result of the action;

So consider an example where you are performing a request something like:

GET api.example.com/1/users?pirate_or_developer=true

Your response JSON will look like:

[{id: 1, name: 'Jordan'}, {id:2, name: 'Guybrush'}]

This JSON should allow the client to update all the records they have that match the records provided in the response. Possibly, it will also allow the client to determine which records have been deleted and can prune its local storage accordingly.

Now, consider an example where you are updating a resource with a request like:

PUT api.example.com/1/users/1

Your response JSON will look like:

{id: 1, name: 'Jordan'}

This allows the client to update its data for the record.

(4xx) Client Error Codes

Here I’ll cover the 3 client error codes I find myself using most in my APIs:

400 Bad Request

The 400 Bad Request status indicates that the request ‘could not be understood by the server due to malformed syntax’. See the IETF docs

There is also the 422 Unprocessable Entity status code that appears to be popular for roughly the same purpose. I’ve read from a couple of sources that since the 422 is part of the WebDAV extension that 400 is preferable over 422. I don’t have the knowledge to weigh in on this argument. Perhaps someone can enlighten us in the comments section.

Some examples scenarios I’ve used an API to return a 400 for:

  1. The client is trying to create a resource with data that fails validation rules on the API
  2. The client is requesting resources using invalid params (e.g.: the date is malformed)
  3. The client request is missing fields the API requires as indicated in the thoroughly written docs! (e.g.: a search might require an end date is a start date is passed through)

What should I return in the 400 response content?

The response of a 400 will depend on why the request failed.

Likely, you’ll want to keep a consistent format across all API end-points. I nest my failure reasons in an errors attribute in the JSON.

As an example, let’s say the client request failed because the name provided was too long. The API will respond with:

{errors: {name: "must be fewer than 18 characters"}}

In fact, given this is being returned with a 400 status code, you can probably do away with the errors wrapper entirely and only return:

{name: "must be fewer than 18 characters"}

The only important thing is to be consistent across your API in how you represent these errors.

401 Unauthorized

The 401 Unauthorized status indicates that the request had missing/invalid authentication credentials. See the IETF docs.

To demonstrate the use of the 401 in an API, I’ll use one of my apps as an example.

In the client application we have a login screen for entering email/password to log in. On all other pages in the application we use token-based authentication (each request must have an token passed through that is checked by the API before performing any request). When the client successfully logs in the API passes a token back that can be persisted on the client device.

In this scenario, the API will return a 401 if:

  1. The client app attempts to authenticate a user by passing invalid username or password
  2. The client app makes a request to an action that requires authentication without providing the token (To be honest, I think this has only ever happened to me in development)
  3. The client app makes a request to an action that requires authentication providing an invalid token (For example: the user tries to log in to the client app after their user has been disabled on the API)

What should I return in the 401 response content?

I’ve found that so far I’ll just return one of:

{errors: {invalid_credentials: 'Authentication credentials provided were invalid'}}

or

{errors: {no_token: 'No authentication token was provided in request'}}

or

{errors: {invalid_token: 'Token provided was invalid'}}

403 Forbidden

The 403 Forbidden status indicates that although the request was valid the action requested failed authorization constraints. See the IETF docs.

Pretty straight forward scenario: user x tries to update resource y. User x is not authorized to update resource y.

As a note, if you are making a client where you strictly control the interactions with the API I feel that your client ever getting an authorization error is at best a code smell but more likely it’s actually just a bug.

Consider an interface that has a button that the user can interact with which returns a message like ‘You are not authorized to perform this action’. Ideally, in a mobile interface the user should never see an authorization error message since it’s not something the user can do anything to fix.

What should I return in the 401 response content?

The API will return a string with a simple error message like:

{errors: {authorization: 'You are not authorized to perform this action'}}

What about the rest of the client error status codes?

So I’ve given you the top 3 error status codes I use in a bit more detail but that’s not an exhaustive guide to the error codes. Here’s a whirlwind summary of the remaining error codes that I’ve used in my APIs:

  1. 404 Not Found for when the URL is wrong or the requested resource does not exist.
  2. 410 Gone for when the resource has been permanently (and intentionally) deleted. This informs the client application that it should remove any references to the resource in question.

Summary

I hope I’ve provided some insight into the various status codes you can leverage to create an accurate, informative API. I also hope I’ve illustrated the strong relationship between the status code and the response body and the importance of providing a descriptive response body.

If you have any thoughts or disagree with me on this let me know in the comments and we can discuss!

Thanks for reading.

My (new) favourite RSpec pattern

Posted in Agile Development, Code, Featured, Inside TFG, Ruby on Rails

I love the RSpec let syntax. I especially love using let blocks to declare everything on the planet. However, I was noticing a lot of duplication in my code so I knocked up the below pattern to deal with the issue:

Can’t see this Gist? View it on Github!

The pattern I’m referring to above is declaring and using the vehicle_attributes object to set attributes on an object. The benefits of this pattern is that I’m able to set specific attributes on an object on a per-context basis without having to re-write my call to the factory. The issue that caused me to start using this pattern was having a declaration at the top of the file that was getting overloaded with ‘common’ attributes. My vehicle declaration started to look like:

Can’t see this Gist? View it on Github!

Which worked well enough until I had 4 common attributes on vehicle and 3 other objects that were being created with multiple common attributes as well. My spec file was starting to get ugly.

Even worse, I was declaring vehicle multiple times within describe blocks for other methods.

So, by using the above pattern you can avoid a fair bit of duplication in your specs and keep everything neat and tidy.

Plus, it’ll reduce the amount of code you have to type which gives you more time to browse r/aww

Case Study: Synaptor – Manage health, safety, and environmental risk in real time

Posted in Agile Development, iPhone, Ruby on Rails, Websites or Tools

This week marks the official launch of a project we have been busy working on for the past few months. Since October we have been putting together mobile and web apps for a startup in Perth called Synaptor.

Synaptor is changing the way SMEs in hazardous industries ensure the safety of their people and the environment with innovative mobile and web apps. We’re happy to have been involved in a project for a local company that is going to improve health and safety outcomes in hazardous industries.

We have put together a case study (Synaptor case study) to showcase the products, but here’s a sneak peek below:

Visit the Synaptor website to check out the project, or try out the mobile apps (iPhone/iPad) in the App Store (ObservationsMaps)

Agile Development Sprints – This is how we do it

Posted in Agile Development, Ruby on Rails, Tips and Tricks

In any given week our company is typically developing five projects at once, with teams of one to three. We run one-week sprints with a half day planning session on Monday morning, and a review session on Friday afternoon.

A sprint is the basic unit of development in Agile. Sprints tend to last between one week and one month and are a “timeboxed” development effort of a constant length.

Our sprint planning session is broken down as follows:

  • Product owner – prioritise and explain highest priority items in the product backlog (we use Pivotal Tracker). The team can ask questions at this point.
  • Product owner – set a sprint goal (what are we achieving this sprint).
  • Team – select Pivotal Tracker stories you can commit to, to attain that goal.
  • Team – demonstrate a solution to each story in the sprint and ensure no outstanding questions.

Our Friday afternoon review session:

  • Product Owner and Team  – demo all completed stories.
  • Team – Review estimates from the sprint and note down how you went and how you can improve (if target not met).
  • Team – Review points missed from the sprint and why, and how you can improve on that for next sprint.

If you’re running sprints in your organisation do you do things a little differently? Drop us a line in the comments.

Learn Ruby with the Ruby Koans

Posted in Agile Development, Code, Inside TFG, Ruby on Rails, Websites or Tools

If you’re looking for an engaging and interactive way to learn Ruby, I’d recommend Ruby Koans by EdgeCase. I think that the koans are especially interesting if you’re coming from another programming language like PHP or Java, because they rely on some basic programming knowledge, but don’t presume any Ruby-specific abilities.

The Koans walk you along the path to enlightenment in order to learn Ruby. The goal is to learn the Ruby language, syntax, structure, and some common functions and libraries.

By manipulating and building upon Ruby’s TestUnit framework, the EdgeCase developers have created a step-by-step process for teaching Ruby through the practice of “Red, Green, Refactor.” They’ve added some simple game mechanics too, by showing your systematic progression through the 270+ challenges (puzzles). Reaching enlightenment results in a pretty ASCII graphic, and a legitimate sense of achievement.

Before you start with the koans though you’ll need a working Ruby installation. I recommend you take a look at the excellent rvm project, which will allow you to install multiple rubies (1.8.7 and 1.9.2 for example, alongside each other) and multiple gemsets in your home directory. Former Frontiersmen and 2011 Ruby Hero Award winner Darcy Laycock was heavily involved in this project as part of the 2010 Ruby Summer of Code, so we really like rvm at TFG.

The GitHub repository even includes a handy Keynote presentation, which I used as the basis for my talk about Ruby Koans at last week’s Ruby on Rails Oceania Perth meetup.

Lastly, if you’d like to have a play with the koans before diving in too deep, they’re available online through your web browser at Ruby Koans Online. This is a no-risk way of trying out Ruby (hint: team them up with why’s Try Ruby project) in your browser.

Search Posts

Featured Posts

Categories

Archives

View more archives