10.1 Domain classes as REST resources

The easiest way to create a RESTful API in Grails is to expose a domain class as a REST resource. This can be done by adding the grails.rest.Resource transformation to any domain class:

  1. import grails.rest.*
  2. @Resource(uri='/books')
  3. class Book {
  4. String title
  5. static constraints = {
  6. title blank:false
  7. }
  8. }

Simply by adding the Resource transformation and specifying a URI, your domain class will automatically be available as a REST resource in either XML or JSON formats. The transformation will automatically register the necessary RESTful URL mapping and create a controller called BookController.

You can try it out by adding some test data to BootStrap.groovy:

  1. def init = { servletContext ->
  2. new Book(title:"The Stand").save()
  3. new Book(title:"The Shining").save()
  4. }

And then hitting the URL http://localhost:8080/books/1, which will render the response like:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <book id="1">
  3. <title>The Stand</title>
  4. </book>

If you change the URL to http://localhost:8080/books/1.json you will get a JSON response such as:

  1. {"id":1,"title":"The Stand"}

If you wish to change the default to return JSON instead of XML, you can do this by setting the formats attribute of the Resource transformation:

  1. import grails.rest.*
  2. @Resource(uri='/books', formats=['json', 'xml'])
  3. class Book {
  4. ...
  5. }

With the above example JSON will be prioritized. The list that is passed should contain the names of the formats that the resource should expose. The names of formats are defined in the grails.mime.types setting of application.groovy:

  1. grails.mime.types = [
  2. ...
  3. json: ['application/json', 'text/json'],
  4. ...
  5. xml: ['text/xml', 'application/xml']
  6. ]

See the section on Configuring Mime Types in the user guide for more information.

Instead of using the file extension in the URI, you can also obtain a JSON response using the ACCEPT header. Here’s an example using the Unix curl tool:

  1. $ curl -i -H "Accept: application/json" localhost:8080/books/1
  2. {"id":1,"title":"The Stand"}

This works thanks to Grails' Content Negotiation features.

You can create a new resource by issuing a POST request:

  1. $ curl -i -X POST -H "Content-Type: application/json" -d '{"title":"Along Came A Spider"}' localhost:8080/books
  2. HTTP/1.1 201 Created
  3. Server: Apache-Coyote/1.1
  4. ...

Updating can be done with a PUT request:

  1. $ curl -i -X PUT -H "Content-Type: application/json" -d '{"title":"Along Came A Spider"}' localhost:8080/books/1
  2. HTTP/1.1 200 OK
  3. Server: Apache-Coyote/1.1
  4. ...

Finally a resource can be deleted with DELETE request:

  1. $ curl -i -X DELETE localhost:8080/books/1
  2. HTTP/1.1 204 No Content
  3. Server: Apache-Coyote/1.1
  4. ...

As you can see, the Resource transformation enables all of the HTTP method verbs on the resource. You can enable only read-only capabilities by setting the readOnly attribute to true:

  1. import grails.rest.*
  2. @Resource(uri='/books', readOnly=true)
  3. class Book {
  4. ...
  5. }

In this case POST, PUT and DELETE requests will be forbidden.