You might say I’m a bit of a fan of the REST architectural style. Let me provide a little background to clarify why REST is important to me, so you can better understand my underlying objectives. If we have similar objective then maybe this series of posts will be of interest to you.
I write distributed business applications for a living and to date, it appears that I end up supporting the code I write for at least 10 to 15 years. When ever you deploy and update distributed systems there is a nasty side effect of having different components to update and trying to deploy them simultaneously is rife with pitfalls. Deploying an update to a server compared with updating software on 50 client machines is just a completely different set of problems and keeping them synchronized can be challenging.
I realize that many people would argue that using a web browser as a client platform would solve my distribution problems. It would solve the distribution problem, but it would also introduce a whole host of other problems for the types of applications I write. Browser based apps are awesome for many things, some things they are not so awesome for.
The REST constraints allow you to manage the coupling between the distributed components and allow them to evolve more independently. This allows the system as a whole to evolve incrementally over long periods of time. I need this kind of robustness in my line of work.
In the three years that I have been building RESTful systems I have seen lots written about how to design and implement RESTful APIs but very little has been written about how REST client applications need to be written. The few people I have seen talk about it are Stu Charlton and Guilherme Silveira.
This is hopefully the first in a series of blog posts where I cover what I am learning about writing client applications that are part of a RESTful distributed system.
REST clients are a different breed
One of the core concepts when designing a REST client is the notion of Hypermedia as the Engine of Application State. I’m not going to try and explain what I think it means, as many people far more eloquent than I, have tried and yet its meaning is still much debated. Instead, I would prefer to show some code that I believe embodies the concept.
My REST client applications are built around a class called RestAgent. I like to imagine my instance of the RestAgent class as little guy travelling across the web making requests and fetching data on my behalf [1]. This agent is responsible for holding all of my application state and for transferring state to and from origin servers.
In its most simple incarnation the class looks something like:
public class RestAgent(HttpClient client) {private Uri _CurrentLocation; private HttpContent_CurrentContent;
public void NavigateTo(Uri url) {
_CurrentContent = client.Get(url).Content; _CurrentLocation = url;
}
}
The RestAgent itself does not know any of the nitty gritty details of how to do HTTP interactions, so I need to provide it with some kind of Http client library. Obviously, I’ve chosen to use the Microsoft Http client, but in theory any library could work.
At this point the only thing that the RestAgent is really capable of doing is navigating to the provided url and retreiving the returned content. The important concept here is that at any one point in time, the RESTAgent can only be in one place. As we expand on the capabilities of the agent we will allow it to accumulate content during its travels and the aggregate of all of that content will be the “application state”, but if our client application really needs to be in multiple places at once, then we will create multiple agent instances.
For just a small taste of how you might use this RestAgent,
var agent = new RestAgent(new HttpClient());agent.NavigateTo(new Uri(“http://api.stackoverflow.com/1.0/questions”)); var questions = agent.CurrentContent.ReadAsJson();
agent.NavigateTo(“http://search.twitter.com/search.atom?q=@@darrel_miller”) var mentions = agent.CurrentContent.ReadAsSyndicationFeed();
In the next post, I’ll talk more about hypermedia and how the agent can use links from hypermedia content to travel further and gather more content.
[1] I originally wanted to call this class AgentFielding to anthropomorphize the class even more, but it seemed a touch presumptuous :-)