Tuesday, February 9, 2010

RESTlet - return different media type based on filename extension

I have developed a RESTful interface to a repository application using RESTlet 1.1 framework. One function of the RESTful interface is to deliver reports. For each report, I would like the ability to change the format of the report resource returned dynamically, and based on the filename extension included in the report resource's URL. For instance, I want .../report.xml to return the report in text/xml and .../report.html to return in text/html.

This seems rather straightforward in a resource oriented architecture. However, I could not find any examples or documentation for how to do this in RESTlet, hence the post. I implemented as follows.

In my Application class, I have defined routing for this resource:
router.attach("/jobs/{jobid}/report",JobReportResource.class);

In the JobReportResource constructor, when defining the kinds of representations supported by this resource, I add Variant based on the URL of the request.
String strReqPath = request.getResourceRef().getPath();
if (strReqPath.matches(".*\/html$")) {
  getVariants().add(new Variant(MediaType.TEXT_HTML));
} else {
  getVariants().add(new Variant(MediaType.TEXT_XML));
}
In getRepresentation, I can now generate the appropriate representation based on the media type of the variant.

Representation representation = null;
MediaType requestMediaType = variant.getMediaType();

if (MediaType.TEXT_XML.equals(requestMediaType)) {
  representation = new DomRepresentation(MediaType.TEXT_XML);
  ...
} else if (MediaType.TEXT_HTML.equals(requestMediaType)) {
  ...
  //transform report into html, set strReport
  ...
  representation = new StringRepresentation(strReport,MediaType.TEXT_HTML);
}