By Michael Woloszynowicz

By Michael Woloszynowicz

Tuesday, May 17, 2011

Why and How You Should Write REST-Centric Applications

Ever since Twitter built their “New Twitter” UI on top of their existing API, the idea of incorporating the very same philosophy into my own applications resonated with me. I decided to move forward with the same approach and my team and I been doing so since September. For those of you that have not taken this route, what I’d like to do is share some of the reasons why you may want to, and some advice on how to make it relatively painless. 

Why?

To begin, let’s address the issue of why writing a REST-centric application, as opposed to one using a homegrown AJAX forwarder or framework provided implementation, is a good idea:
  • It provides a uniform interface
  • It’s expressive, REST paths and CRUD requests are easy to understand and hypermedia makes it easy to navigate
  • You write your back-end once and can re-use it on a web client, a mobile app, or public API
  • You get clean exception handling via HTTP status codes
  • The stateless nature of REST removes dependencies and promotes loose coupling, makes for easy debugging, and produces maintainable code. It also reduces the amount of data stored in your application session, making your app less memory intensive. 
  • It’s easy to do, anyone can learn the principles of REST in a day. Implementing the server and client side code is trivial in most languages. 
  • Its cacheable nature helps with scalability
  • With tools like Jersey and JaxB (Java or Scala), marshalling and un-marshalling complex PUT/POST and response data as XML or JSON is a breeze
  • It forces to you think in terms of layers and discrete pieces of logic, making development easier and producing better code
  • It’s fun, I've personally never enjoyed writing web applications as much as I do now
How?

Now that we’ve dispensed with why this is a good idea, let’s go over how best to approach this based on the issues I’ve run into over the past few months. 

Find Good Tools
Provided you use a good set of tools, REST can be a very easy thing to get started with. As I’ve mentioned, in the case of Java/Scala, I’ve been using Jersey and have nothing but good things to say about it. Setup is simple with only a few lines of XML, and the creation of a REST resource requires nothing more than a method declaration and 2-4 lines of annotations. For almost all popular language there are several solutions of varying quality so talk to developers in your community to find out what works best for them (perhaps you can provide some suggestions in the comments as well). This is particularly important for newer frameworks like Node.js which has several REST implementations, all of which are not very mature and vary in quality. 

In addition to the REST framework, be sure to find a good JSON/XML parser since your PUT and POST content will likely be in this form. Again, for Java/Scala I use JaxB, and it has worked splendidly. JaxB marshals and un-marshals JSON or XML data by creating a simple entity object (or POJO in Java speak) and adding a few lines of annotations. Best of all it can work interchangeably with JSON or XML, depending on how your REST resource is defined, allowing you to provide support for multiple data formats without any additional coding. Given the amount of data passing you will do, this can save you a great deal of time so I urge you to find a good solution to deal with these low level details. 

Design an Authentication Scheme
Before you hit the ground running and write a whole bunch of REST resources, I urge you to spend some time thinking about how you’ll authenticate users. Since you’ll likely want to make a good chunk of your resources public, you’ll need an authentication mechanism that works beyond the walls of your web server’s application session. Although it’s not without its share of problems, we chose OAuth 2.0 given its high level of adoption and developer familiarity, and overall it’s worked quite well. You’ll want to design your server architecture so that one or more independent servers provide the authentication mechanisms and share the data with your web servers. Doing this - along with the stateless nature of REST - will also make it easier to use automatic load balancing services like Amazon’s Elastic Load Balancer in the future.

What’s Public, What’s Private?
Before you start development, have a clear plan as to what resources you intend to make public and which are private. This will have implications for your authentication mechanism as well as the structure of the request and its content. I recommend always thinking about every resource as though it was a public one, as this generally forces you to create a cleaner and more robust implementation. Remember that you may want to use these resources for clients other than web browsers, e.g. an iPhone or iPad application. Although this should be the case for all your resources, it’s especially important that your public resources use hypermedia, thus making it a true REST implementation. Finally, regardless of whether it is a public or private resource, be sure to enforce the stateless constraint at all costs. It can be very easy to get lazy about this as it requires some additional legwork, but I promise you it will pay dividends in the end. 

Standardize
Meet with your team and decide on a structure for your REST paths and how the resources will be divided up and structured. We tend to have one class house all resources (each resource is a method in our case) for operating on particular data class, but there is no right answer here. The important thing is to come up with a package structure that works for you and that everyone sticks to. Since you’re likely to have a huge number of resources by the time you’re done, it will make debugging much easier if you know where to look for the code based solely on the resource name and operation. 

Extend your AJAX Mechanism
Regardless of what client side framework your using to perform AJAX CRUD requests it’s highly advisable that you create either a wrapper method in the case of jQuery’s ajax() method, or a wrapper class in the case of Dojo’s xhr() methods. If you’re using jQuery you may want to look into the JSON-REST plugin and build from there. Since we’re using Dojo, we created a base class that provides the following helpers:
  • Takes care of obtaining and managing OAuth refresh and access tokens by tracking token expire times and fetching new tokens when needed. By doing this we can still make a CRUD request in a normal fashion but if a token has expired, the request will be deferred until a token refresh is completed. Once a new token is received, our base class appends the token to our original request and submits the request. 
  • Takes care of error alerting if we ask it to. Depending on the error codes we can have our base class handle certain types of errors in a variety of ways. For example, in the case of a 401 code (the session has expired) we can bring up a login dialog and have the user re-authenticate and continue their workflow. For other codes we can simply display a modal dialog with an error message, and so on. 
  • Since all requests flow through our base class, we can have it provide timeout warnings if we choose to use one.  
  • We've added extensions to simplify filling in dynamic data into the REST path, e.g if we have a path like /rest/user/{userId}, we can simply add a map from userId -> value in our request and the data will be populated into the request path. 
The list of helpful things that can be added goes on and on, and you discover more of them as you go along. If you start with a central place to route all of your requests through, it becomes much easier to layer on additional functionality as you discover the need for it. 

This also applies to your back-end as you’ll want to decorate your REST resources with any authentication code that will be checked with every request. 

Use a Service Layer
Although this is a fundamental principle that every good web developer knows, I can’t emphasize how important this is in the context of a REST-centric application. Rather than having several large actions that process or set data, you’ll now have many individual resources that often make use of the same data and business logic. If you forgo the service layer you'll find yourself with a great deal of code repetition by the time you're done. Having a clear service layer will make your life much easier, and your application more maintainable in the long run. 

Although a REST-centric approach requires a bit more work on the front-end, as just about all requests must be made through AJAX, it will help you produce a much better product and you’ll have a lot of fun in the process. Hopefully this will encourage you to begin writing REST-centric applications and save you from some of the mistakes my team and I have made along the way. 

If you liked this post, please Tweet it, upvote it on Hacker News, or follow me on Twitter for more.

If you've found any good REST tools for your respective language/framework, please share them in the comments. 

3 comments:

  1. Great post. Would love to hear more about how you implemented authentication scheme

    ReplyDelete
  2. "Please note that this approach should not be used if your pages need to be crawled by search engines"

    Can you explain your reasoning behind that? I don't see how a REST based structure prevents crawlers from doing their thing, unless you bring authentication into the mix.

    ReplyDelete
  3. You've made a *lot* of generalizations and pimped up REST so much that it seriously brings down the credibility of the article. Any downsides to REST or does it solve all my problems? Also you use so many buzzwords and acronyms that it almost seems the goal is to look impressive (you don't) rather than convey a message.

    ReplyDelete