We can write a RESTful application with Grails and define our API in different ways. One of them is to subclass the grails.rest.RestfulController. The RestfulController already contains a lot of useful methods to work with resources. For example all CRUD methods (save/show/update/delete) are available and are mapped to the correct HTTP verbs using a URL mapping with the resource(s) attribute.

We can define which content types are supported with the static variable responseFormats in our controller. The variable should be a list of String values with the supported formats. The list of supported formats applies to all methods in our controller. The names of the formats are defined in the configuration property grails.mime.types. We can also use a Map notation with the supportedFormats variable. The key of the map is the method name and the value is a list of formats.

// File: grails-app/controllers/com/mrhaki/grails/UserApiController.groovy
package com.mrhaki.grails

import grails.rest.*

class UserApiController extends RestfulController {

    // Use Map notation to set supported formats
    // per action.
    static responseFormats = [
        index: ['xml', 'json'],  // Support both XML, JSON
        show: ['json']           // Only support JSON
    ]

    // We make the resource read-only in
    // the constructor.
    UserApiController() {
        super(User, true /* read-only */)
    }

}

We can also specify supported formats per action using the respond method in our controller. We can define the named argument formats followed by a list of formats when we invoke the respond method. In the following controller we override the index and show methods and use the formats attribute when we use the respond method:

// File: grails-app/controllers/com/mrhaki/grails/UserApiController.groovy
package com.mrhaki.grails

import grails.rest.*

class UserApiController extends RestfulController {

    // We make the resource read-only in
    // the constructor.
    UserApiController() {
        super(User, true /* read-only */)
    }

    @Override
    def index(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        respond listAllResources(params), formats: ['xml', 'json']
    }

    @Override
    def show() {
        respond queryForResource(params.id), formats: ['json']
    }

}

Code written with Grails 2.4.2.

Original article

shadow-left