Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Build a RESTful Web service

An introduction to REST and the Restlet framework

Andrew Glover (aglover@stelligent.com), President, Stelligent Incorporated
Andrew Glover is president of Stelligent Incorporated, which helps companies embrace developer testing strategies and continuous integration techniques that enable teams to deliver software faster. Check out Andy's blog for a list of his publications.

Summary:  Representational state transfer (REST) is a style of designing loosely coupled applications that rely on named resources rather than messages. The hardest part of building a RESTful application is deciding on the resources you want to expose. Once you've done that, using the open source Restlet framework makes building RESTful Web services a snap. This tutorial guides you step-by-step through the fundamental concepts of REST and building applications with Restlets.

Date:  22 Jul 2008
Level:  Intermediate PDF:  A4 and Letter (161 KB | 27 pages)Get Adobe® Reader®

Activity:  266913 views
Comments:  

Restlets

You've defined a RESTful API that maps quite nicely to CRUDing races and runners. And you've defined the format of the communication: XML documents. In this section, you'll start to put this all together using an innovative framework that is modeled after servlets.

The Restlet framework

Restlet applications are akin to servlet applications in that they reside in a container, but in practice they are quite different in two major ways. First, Restlets use no direct notion of HTTP or its stateful manifestations such as cookies or sessions, per se. Second, the Restlet framework is extremely lightweight. As you'll see, a fully functional RESTful application can be built with a handful of classes that extend from a few core Restlet base classes. Configuration and deployment leverage existing container models, so you simply update the customary web.xml file and deploy a standard Web archive (WAR) file.

For the most part, the bulk of a RESTful application built with the Restlet framework requires the use of two base classes: Application and Resource. Logically speaking, an Application instance maps URIs to Resource instances. Resource instances do the work of handling the basic CRUD commands, which are, of course, mapped to GET, POST, PUT, and DELETE.


The race application

You create a starting point with the Restlet framework by extending from the framework's Application class. In this class, you define Resources that respond to URIs. This definition process is done with the framework's Router class. For example, if you have a URI such as order/order_id, you need to specify which object can handle these requests. This object is an instance of the framework's Resource type. You link objects with URIs by attaching them to a Router instance, as in Listing 5:


Listing 5. Creating Router instances and mapping URIs
                    
Router router = new Router(this.getContext());
router.attach("order/{order_id}", Order.class);

So in this example, the URI order/order_id is logically mapped to an Order class (which, in turn, extends Resource).

Acme Racing has the four logical RESTful URIs that you've already defined — four patterns that work with various aspects of races and runners:

  • /race
  • /race/race_id
  • /race/race_id/runner
  • /race/race_id/runner/runner_id

The behavior of each URI (such as if it works with POST, DELETE, GET, and so on) isn't important at this point. The behavior of each Resource is the job of a Resource instance; however, the Application instance is used to map these URIs to (yet-to-be-defined) Resources via a Router instance, as shown in Listing 6:


Listing 6. Mapping Acme Racing's URIs to Resources
                    
public class RaceApplication extends Application{
 public RaceApplication(Context context) {
  super(context);
 }

 public Restlet createRoot() {
  Router router = new Router(this.getContext());
  router.attach("/race", RacesResource.class);
  router.attach("/race/{race_id}", RaceResource.class);
  router.attach("/race/{race_id}/runner", RaceRunnersResource.class);
  router.attach("/race/{race_id}/runner/{runner_id}", RaceRunnerResource.class);
  return router;
 }
}

The base class, Application, is an abstract class. Extending classes must implement the createRoot() method. In this method, you can create a Router instance and attach Resources to URIs as I've done in Listing 6.

As you can see, there are four different Resource classes. I've named them to match the desired high-level behavior of the URI. For instance, the /race URI is intended to work with multiple race instances; consequently the Resource type is named RacesResource. Once an id is included in the URI (/race/race_id), the implication is that a single race is being manipulated; accordingly, the Resource type is apply named RaceResource.


Race resources

Now that you've defined the Application instance to handle four different URI patterns, you must implement the four Resources.

Resource types in the Restlet framework are known as Restlets. They are the heart of any RESTful application developed with the Restlet framework. Unlike the Application type, the base Resource class is not abstract. It's more like a template with default behavior that you can override as needed.

At a high level, Resource has four methods that require overriding. Not coincidentally, they map to the basic HTTP commands that are the touchstone of REST — GET, POST, PUT, and DELETE. Because the Resource class is nonabstract, the framework requires a paired method to be implemented for desired behavior to be invoked. For instance, if you want a particular resource to respond to DELETE requests, you would first implement the delete() method. Second, you also must implement the allowDelete() method and have this method return true (it defaults to false). By default, the corresponding PUT, POST, and DELETE allow methods return false, and the allowGet() method returns true. This means for read-only Resources, you need to override only one method (instead of two in the other three cases). You can alternatively call the setModifcation(true) in a Resource class and thus not have to override individual HTTP verb allow methods.

For instance, the RacesResource is intended to respond to GET requests with an XML document that describes the races in the system. Users can also create new races via this Resource type. Therefore, the RacesResource class overrides at least three methods from the Resource base class:

  • getRepresentation()
  • allowPost()
  • post()

Remember, Resources instances, by default, are read-only. Hence the allowGet() method doesn't need to be overridden.

5 of 14 | Previous | Next

Comments



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, SOA and web services, Open source
ArticleID=322195
TutorialTitle=Build a RESTful Web service
publish-date=07222008
author1-email=aglover@stelligent.com
author1-email-cc=