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. 


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

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. 

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. 

Monday, May 9, 2011

Giving Developers Feedback

As a product manager, founder, CEO, developer, etc., you've undoubtedly had to provide developers with negative feedback on one or more feature implementations. What I would like to emphasize is that the way in which you deliver this feedback greatly impacts the success of that feature as well as the productivity and output of your developers going forward.

To make the advice more memorable, I've consolidated it into point form:
  • Critique is necessary for creating a great product, but done wrong it can lead to a terrible product.
  • Know that when designing and implementing a feature for the first time, both you and the developer are probably wrong. Iteration, not interpretation, is the only way to perfect a feature. Rapid iteration through continuous deployment is the beauty of writing web applications. 
  • Never design by assumption, if something is wrong explain why it's wrong based on quantitative or qualitative data. Simply saying something is wrong is not helpful, if you can't justify it based on some form of user interaction or UX pattern violation, it's probably not wrong. Good developers won't argue with concrete evidence. 
  • Try not to provide solutions, re-iterate the problem you are trying to solve and let your team design a solution. 
  • Backtracking and changing the implementation of a feature when it's ready for deployment is a form of waste. The feature will be not be perfect either way so release it to a small percentage of users and iterate from there. 
  • Few things anger a developer more than working overtime for weeks on a feature, only to have its deployment delayed at the 11th hour due to trivial issues. Unless there is a tremendous oversight (which there shouldn't be at this stage), deploy at all costs, even if only to a small percentage of users. 
  • Ask your developer how they arrived at their solution, what was their interpretation of the problem? They may know something you don't. 
  • When a developer is working on a large feature for an extended period of time, they become emotionally attached to their work. If you put down their work you are effectively putting them down. When giving feedback don't dwell on small oversights or issues, emphasize the positives and discuss what can be improved going forward. Make a list of potential changes and validate them through user feedback. 
  • If you are non-technical, always remember that there is more to a feature than meets the eye. On the surface Google search is just one text input box, that doesn't make it easy to implement. If something took longer than expected or failed, ask where the challenges were and what could have been done to avoid it. Remember, you're not just trying to improve this feature but all features going forward. 
  • If you've hired right, your developers and designers are skilled and creative people. Trust that given the right information they will produce a good product. Your job as a member of the customer development team is to provide this information through insight about the end user and their problem. 
  • Keep feedback meetings short, ideally no more than 15-30 minutes. Nobody wants to hear about how bad something is, or potential solutions for hours on end. Developers want insightful advice and then get sent off to work on it. 
  • Follow the principles of the lean startup where iteration and improvement is based on feedback loops. Remember that a loop must always start with delivering the feature.
Developers are not timid creatures that can't handle feedback, but the best developers are passionate about their work and view their work as a reflection of themselves. They genuinely want to create a great product, but to do so they need feedback, direction, and information, not conjecture.

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