Using the respond method to output JSON

    The respond method provides content negotiation strategies to intelligently produce an appropriate response for the given client.

    For example given the following controller and action:

    grails-app/controllers/example/BookController.groovy

    The respond method will take the followings steps:

    • If the client Accept header specifies a media type (for example application/json) use that

    • If the file extension of the URI (for example /books.json) includes a format defined in the grails.mime.types property of grails-app/conf/application.yml use the media type defined in the configuration

    The respond method will then look for an appriopriate Renderer for the object and the calculated media type from the .

    Grails includes a number of pre-configured Renderer implementations that will produce default representations of JSON responses for the argument passed to respond. For example going to the /book.json URI will produce JSON such as:

    1. [
    2. {id:1,"title":"The Stand"},
    3. {id:2,"title":"Shining"}
    4. ]

    Controlling the Priority of Media Types

    However if your application is primarily an API, then you can specify the priorty using the responseFormats property:

    grails-app/controllers/example/BookController.groovy

    1. package example
    2. class BookController {
    3. static responseFormats = ['json', 'html']
    4. def index() {
    5. respond Book.list()
    6. }
    7. }

    In the above example Grails will respond by default with json if the media type to respond with cannot be calculated from the header or file extension.

    Using Views to Output JSON Responses

    If you define a view (either a GSP or a JSON View) then Grails will render the view when using the respond method by calculating a model from the argument passed to respond.

    For example, in the previous listing, if you were to define grails-app/views/index.gson and grails-app/views/index.gsp views, these would be used if the client requested application/json or text/html media types respectively. Thus allowing you to define a single backend capable of serving responses to a web browser or representing your application’s API.

    When rendering the view, Grails will calculate a model to pass to the view based on the type of the value passed to the respond method.

    The following table summarizes this convention:

    Using this convention you can reference the argument passed to from within your view:

    You will notice that if Book.list() returns an empty list then the model variable name is translated to emptyList. This is by design and you should provide a default value in the view if no model variable is specified, such as the List in the example above:

    grails-app/views/book/index.gson

    1. // defaults to an empty list
    2. @Field List<Book> bookList = []
    3. ...

    There are cases where you may wish to be more explicit and control the name of the model variable. For example if you have a domain inheritance hierarchy where a call to list() my return different child classes relying on automatic calculation may not be reliable.

    In this case you should pass the model directly using respond and a map argument:

    1. respond bookList: Book.list()

    If you simply wish to augment the calculated model then you can do so by passing a model argument:

    The above example will produce a model like [bookList:books, bookCount:totalBooks], where the calculated model is combined with the model passed in the model argument.

    Using the render method to output JSON

    The render method can also be used to output JSON, but should only be used for simple cases that don’t warrant the creation of a JSON view:

    1. def list() {
    2. def results = Book.list()
    3. render(contentType: "application/json") {
    4. books(results) { Book b ->
    5. title b.title
    6. }
    7. }
    8. }

    In this case the result would be something along the lines of:

    1. [
    2. {"title":"The Stand"},