Grails Goodness: Change Response Formats in RestfulController
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.