Skip to content

Grails 2.3: REST Improvements

graemerocher edited this page Apr 30, 2013 · 16 revisions

Details on the upcoming improvements to REST support for Grails 2.3

!!THIS DOCUMENT IS A DRAFT / WIP AND IS NOT FULLY FLESHED OUT YET!!

Proposal: REST Client Improvements

Grails currently ships with no built in web services client library. This means users often get lost trying out one of the available plugins or try to use the abomination that is Groovy's WSClient library.

Grails needs to ship with both a lower level REST client and a higher level client that allows unmarshalling of JSON or XML responses (conversion to domain or POGO instances).

Low-Level client

The proposal for the low level client is to port and enhance the rest-client-builder plugin into Grails data, integrating it with the new Async programming APIs for Grails.

High-level Client - GORM for REST

The higher level client, which will use the low-level client internally, will build on the Grails Data APIs and provide a GORM implementation for REST

class Book {
    
    String title

    static mapWith = "REST"
    static mapping = {
         endpoint "/books"
         format "xml"
    }
}

Instances can be retrieved an unmarshalled with the regular get method (which will issue a GET request):

def b = Book.get(1)

Or asynchronously:

Book.async.get(1).onComplete { book ->
    ..
}

Creating a new resource can be done with save (which will issue PUT with the marshalled object):

new Book(title:"The Stand").save()

Updating a resource can be done with 'save' on an existing resource (which will issue a POST with the marshalled object):

def b = Book.get(1)
b.save()

Basic GORM queries are supported are supported with query parameters:

def b = Book.findByTitle("The Stand") // Query /book?title=The%20Stand

For more advanced queries, one proposal is to support MongoDB's JSON query format (TBD).

Marshalling and unmarshalling is done automatically unless a marshaller or unmarshaller is specified:

static mapping = {
    marshaller { obj, xml ->
        xml.book(title:obj.title)
    }
    unmarshaller { obj, xml ->
        obj.title = [email protected]()
    }
}

The marshaller and unmarshaller can either be a closure or a class that defines marshall and unmarshall methods.

Proposal: REST Server Improvements

Current versions of Grails feature some REST support, but it has limitations and requires more work than necessary. It is also not integrated within any client-side support and the integration with URL mappings is weak.

URL mappings need to be extended to be aware of the HTTP method, and the current 'resource' linking mechanism extended to allow nesting of resources and representation of both single (no id) and multiple resources.

A URL mapping such using resource will change to

"/book"(resource:'book')

Will create URL mappings like:

URL Grails Action
GET /book/create create
POST /book save
GET /book show
GET /book/edit edit
PUT /book update
DELETE /book delete

A URL mapping such as, using resources instead of resource

"/books"(resources:'book')
URL Grails Action
GET /books index
GET /books/create create
POST /books save
GET /books/1 show
GET /books/1/edit edit
PUT /books/1 update
DELETE /books/1 delete
Clone this wiki locally