Why and When to Use REST
At the Google I/O 2010 conference, Virgil Dobjanschi made a great presentation about implementing REST (representational state transfer) clients in Android, titled Developing Android REST Client Applications. His premise is that Android applications should have a separation between state synchronization and state presentation, and that REST makes doing this much easier.
Virgil’s proposed REST architecture makes it so that a user can begin downloading content, and regardless of what they do with the client (like quitting before the download completes) that content will be ready upon their return. Furthermore, since REST architecture assumes that every unique URL represents a unique state, the user can be sure that the downloaded data is up-to-date. In cases where content is being modified often or needs to be in real time, the server should explicitly prevent cached results (the approach used on auction sites and web stores with a shopping cart).
REST is ideal when the information being presented by the client application has semi-permanence, such as the content of a social network timeline or the history of a chat room. This is because there’s a good chance that it will still be up to date in several hours or days.
Nowadays, most applications that present online content for users are REST clients, and there are tons of services and startups developing mobile versions of their products using REST. However, not all online applications need to be REST clients. As with all technologies, it’s important to understand when you need to develop a REST client application.
In order to be RESTful, an application must fulfill two requirements which improve scale and performance, but if the app violates either of those constraints it cannot be considered RESTful.
What It Means to Be RESTful
Have Unique URIs
A RESTful application must have different states presented to the consumer, and each of these states must have a unique uniform resource identifier (URI) to describe it.
For example, consider a catalogue with a unique page for each product. If the URL formula is something like server.com/catalogue/?item=XX
, a toaster might have the page url of server.com/catalogue/?item=toaster9000
. Likewise, if an account screen is needed, something like server.com/account
exists, and a profile page might be server.com/profile
, and so on.
Use Stateless Server-Side Data Storage
All data in a RESTful application should be stored on the server-side. When the client-side needs to define its state with that data, it queries the server with just enough information to get what it needs, and the server merely serves a response. It doesn’t know anything about the user’s context.
This can be trickier than it sounds. Consider a chat application where each chat message has a dialogue ID linking it to the conversation it belongs to. Standard chatroom behavior is to track the current state of the dialogue and only deliver the most recent chat message, once, to the user. If the current state of the dialogue is stored on the client side, that’s RESTful, but if it’s stored on the server (for example, the server knows what chat room the current user is in, and the only necessary info to send a new message is the user’s text, but not the whole information chatid+message), the application is in violation of the REST rules.
REST Patterns
Libraries That Make REST Simple
While one could implement every pattern described by Virgil in his Google I/O presentation, or create custom logic following REST rules by him or herself, reinventing the wheel isn’t worth it. There are many libraries that address the main uses of REST, and I suggest two libraries in particular: RoboSpice and Retrofit.
RoboSpice provides a flexible cache out-of-the-box, so you only need to configure how long a response should be cached, and during that period of time you will receive the saved response. You don’t need to think about the network magic beyond what is needed for the business logic of the application. The main disadvantage of this library, from my point of view, is that you need to describe all of your application’s requests in different classes. If a different return type is needed, likewise a new class is needed. If you need different parameters in a pre-existing request, a new class is needed and so forth. This can get messy.
The other library I recommend, Retrofit, encapsulates calls to your web service by allowing you to describe your backend URLs as interface methods. It turns your HTTP API into a Java interface, and so you can return data from your model to the web service endpoint.
For example, in Java normally you might have:
ReturnType getSomeData(ParamType parameter);
While with Retrofit, the method is annotated with a back-end URL:
@GET("/rest_path/")
Try these libraries and others, find the way you like to solve your problems, and maybe you’ll be inspired to implement your own library!