RESTing at ease with JSR 311

REST is a style of designing loosely coupled Web applications that rely on named resources rather than messages. Ingeniously, REST piggybacks on the already validated (and successful, don’t you think, man?) infrastructure of the Web– HTTP. That is, REST leverages aspects of the HTTP protocol such as GET and POST requests. Because it’s REST’s bag, RESTful applications turn out to be quite clean in their API as you don’t spend a lot of time reinventing the wheel– you get a lot for free when leveraging HTTP.

I’ve been keeping my eye on JSR 311 as it seemed to make a lot of sense to leverage attributes given the template-like pattern employed by the Restlet framework. For instance, without attributes (and by correlation, JSR 311, which is supported by a developmental version of the Restlet framework), you are forced to override specific methods in the base framework’s hip Resource class associated with HTTP verbs– public void post(Representation representation) handles HTTP POSTs; what’s more, given that the framework doesn’t actually know if a subclass has implemented a particular method, you must also override the allowPost method in the case of POST.

In fact, leveraging attributes in the case of JSR 311 (or, as previously mentioned, the 1.1 snapshot version of the Restlet framework) is a lot like comparing JUnit 3.8.1 to JUnit 4– the entire framework paradigm is shifted, which has the result of a lot less noise (a.k.a code).

For instance, implementing a GET request via JSR 311 is as easy as leveraging the GET attribute:

@GET
@ProduceMime("text/xml")
public String get() {
 Collection<Race> races = Race.findAll();
 return this.reporter.racesToXml(races);
}

Note, this code is leveraging Jersey, Sun’s reference implementation of JSR 311 (which recently released version 0.8). What’s more, JSR 311 specifies mime annotations for both requests and responses — for instance, the get method above responds with a mime type of “text/xml” — you can easily specify JSON, etc too.

Handling other requests, such as a POST request is just as easy– just use the corresponding copasetic annotation (for instance @POST). Note too, with mime types, you can specify accepted request types. In the case below, the post method will only accept “text/xml”.

@POST
@ConsumeMime("text/xml")
public Response post(String xml) throws Exception {
 long id = this.consumer.createRace(xml);
 return Response.created(uriInfo.getBaseUriBuilder().
    path(Long.toString(id)).build()).build();
}

Of course, the two method above are related to a particular path or URI– JSR 311 supports the @Path annotation, which interestingly enough, is inheritable such that a method can expand upon a base path specified at the class level. For instance, the method above live in class defined as follows:

@Path("/race")
public class RacesResource {
  //...
}

Thus, all exposed RESTful methods will respond to the /race URI (i.e. a HTTP GET to /race will be handled by the get method and a HTTP POST to the /race URI will be handled by the post method (provided the request be of mime type “text/xml”, don’t forget!)). Methods can expand upon the /race URI by providing their own @Path annotation, which will effectively append the specified URI to the base URI.

There are certainly more than a few ways to skin the REST cat in Java, baby– you’ve got, to name a few, Restlets, Grails, 1060 NetKernel, and now JSR 311 via Sun’s Jersey. Each framework comes with its own bells and whistles; nevertheless, JSR 311 and Jersey definitely lower the barrier for building (and deploying) RESTful applications even if they are fairly late to the party.

Post to Twitter

Related odds and ends
 

5 Responses to “RESTing at ease with JSR 311”

  1. on 17 Jul 2008 at 6:00 pm Jerome Louvel

    Hi Andy,

    I’d like to add a precision. With Restlet API’s Resource class, you are not ‘forced’ to override the allow*() methods.

    In fact, there are two levels, the lower one is part of Handler, Resource’s super class:
    allow*() methods
    handle*() methods

    Those are dynamically discovered and invoked. It’s not necessary to override them in subclasses. You can however, support extension HTTP methods like allowMove() and handleMove() if needed.

    The higher level is indeed in the Resource class:
    is/setReadable() methods used by allowGet(), allowHead()
    is/setModifiable() methods used by allowPost(), allowPut(), etc.
    getVariants() and represent(Variant) called by handleGet() and handleHead()
    storeRepresentation(Representation) called by handlePut()
    acceptRepresentation(Representation) called by handlePost()
    – etc.

    It’s just that by default we forbid modification methods. To change that, just call setModification(true) in your Resource subclass’s constructor.

    It also allows a finer grained control as some users might have read-only access while other with have modification rights. So, this can’t always be described at developement time like in JSR-311, you might need to actually take a look at the handled request, for example for credentials.

    Nice post otherwise!

    Best regards,
    Jerome

  2. on 18 Jul 2008 at 7:54 pm Andy

    Jerome- thanks for clarifying my comment– indeed, the call to setModification(true) is exactly what I missed. FYI, keep your eyes peeled for a Restlet tutorial over at IBM developerWorks, baby!

    One thing that stands out with JSR 311 that is solved with Restlets more easily is Security– do you have insight into security w/respect to JSR 311? Is it something that will eventually make it into the spec or is it just handled by containers and JSR 250?

  3. on 20 Jul 2008 at 3:30 pm Jerome Louvel

    Hi Andy,

    You’re welcome. As for a Restlet tutorial on developerWorks, hmmm… it sounds pretty cool :-)

    Regarding JAX-RS security, there is only a SecurityContext interface that can be injected. The responsability for actual authentication and authorization is left to the parent container (Restlet, Servlet, etc.).

    https://jsr311.dev.java.net/nonav/releases/0.9/javax/ws/rs/core/SecurityContext.html

    Best regards,
    Jerome


  4. [...] state transfer (also known as REST, baby) is an approach to designing loosely coupled applications that rely on named resources rather [...]

  5. on 18 Apr 2009 at 6:46 am Recent URLs tagged Disco - Urlrecorder

    [...] recorded first by Msmay25 on 2009-03-04→ RESTing at ease with JSR 311 [...]