Wednesday, July 8, 2009

JSR 311 plugin for Grails

Project homepage: grails-jaxrs

Recently, I wanted to make a full two-weeks mountain bike tour through the Alps but bad weather on a few days caused me to make detours on the less rocky roads of JSR 311 (JAX-RS: The Java API for RESTful Web Services). I took the chance reading the spec, did some hacking with Jersey and I must really say I like to work with it. I liked it so much that I started to use it inside Grails to combine it with features such as GORM and XML and JSON marshalling.

From my experiments I factored out what I think is reusable into a Grails plugin named grails-jaxrs and made it open source. The plugin takes care of initializing Jersey inside a Grails application, implements a controller that does the dispatch to Jersey and provides some Grails-specific entity provider implementations.

Here's a very simple example of a resource class that represents a collection of notes and that makes use of Grails object relational mapping (GORM) and XML marshaling:

import grails.converters.*

import javax.ws.rs.Consumes
import javax.ws.rs.GET
import javax.ws.rs.Path
import javax.ws.rs.PathParam
import javax.ws.rs.POST
import javax.ws.rs.Produces
import javax.ws.rs.core.Response
import javax.ws.rs.core.UriBuilder

@Path('/notes')
class NotesResource {

@POST
@Consumes('text/plain')
@Produces('text/xml')
Response addNote(String text) {

// Create new Note object and store save it to DB
def note = new Note(text:text).save()

// Construct the URI for the newly created note
URI uri = UriBuilder.fromPath(note.id as String).build()

// Return an XML representation of the note object
// along with a Location response header with the URI
Response.created(uri).entity(note as XML).build()
}

@GET
@Produces('text/xml')
Response getNotes() {

// Find all notes in the database and return
// an XML representation of the note list
Response.ok(Note.findAll() as XML).build()
}

}

A note is an object that contains some text. Notes are instances of the Note Grails domain class. A collection of notes are made available through a RESTful service interface using the above NotesResource class and the grails-jaxrs plugin. A POST to http://host:port/notes/ creates a new note. A GET to http://host:port/notes returns an XML repsresentation of all existing notes in the database. For more details refer to the getting started tutorial.