Blogger: Anne Thomas Manes
The folks at InfoQ have been doing a nice job putting together information about REST. SOA Lead Editor Stefan Tilkov posted A Brief Introduction to REST in December, which explains REST in simple terms and provides some basic examples of the model. For those looking to delve more deeply into the REST architectural style, I recommend reading Mark Baker's article, Hypermedia in RESTful applications. As Mark says at the start of the article, "Hypermedia as the engine of application state" (HATEOAS) is arguably the most important constraint in REST.
The most recent REST article posted on InfoQ is a follow-up article by Stefan, entitled Addressing Doubts About REST. He starts off by addressing the issue I hear most often from developers who inherently resist the notion of constraining an application to a uniform interface: "REST may be usable for CRUD but not for *real* business logic". Stefan explains how GET, PUT, POST, and DELETE can be used to accomplish a variety of functions that deliver more value than just create, read, update, and delete (CRUD) of data, and he shows an example of using GET to call a calculation function. But I don't think he effectively dispels this concern. And that's because he doesn't go the next step to talk about resource models.
REST is fundamentally about resources. Every "thing" that anyone might ever want to access or manipulate is a resource. And what that means, in practical terms, is that an application's interface is defined by the resources that it exposes (i.e., its resource model). Thinking in terms of resources rather than objects and methods requires a fundamental shift in application design. This is the biggest challenge that the typical OO developer is likely to have in adopting REST. If you're working on a RESTful application, and you find that you just can't support the functions you need without tunneling an RPC through POST, then you should go back and reassess your resource model.
Joe Niski is right now working on a revision of our report on Ruby on Rails, and one of the coolest features in Rails 2.0 is its inherent support for REST via the resource_controller plug-in. It automatically generates a resource model that exposes the application's data model as RESTful resources. See the InfoQ article by Rick DeNatale for more information, Rails: Resource_controller Plugin Put Controllers on a Diet.
Rails 2.0 is a really nice framework for building RESTful web applications, but the Rails sweet spot is focused on relatively simple applications based on relatively simple data models performing basic CRUD operations. If the application requires more complex processing, Rails is not such a good option. It requires a lot of complex coding to do complex things. So this brings us back to the big issue raised by Stefan: What to do if the application needs to do more than simple CRUD?
The answer is to use an abstraction layer. Keep in mind that a RESTful application's interface is defined by its resource model. Also keep in mind that the resource model does not need to map one-to-one to methods in the application's object model. And here's where many supposed "REST" frameworks tend to fall down. Most service frameworks invariably map the application's object model directly to its resource model. This approach often leads to non-RESTful POX services that violate RESTful principles. For example, a framework might map a setter method to a GET operation:
This is an extreme no-no. A GET operation should never update a resource. But how is a framework supposed to know whether a particular object method is "safe"?
That's why it's a good idea to start designing a RESTful application by defining its resource model. You need to ensure that you can expose all the required capabilities of the application through resources that support the uniform interface (GET, PUT, POST, and DELETE). From there, you can map the resource methods to code that implements the required capabilities.