JSON Views

13 Apr 2016

Tags: Grails, JSON, REST

We recently published another Grails Quickcast, brought to you in collaboration with DZone. In case you missed the first episode, visit dzone.com/articles/oci-and-dzone-present-a-grails-quickcast-1 to view the epside on Grails 3 Interceptors.

The latest episode introduces JSON Views, a really simple yet powerful tool supported by Grails 3 for describing the JSON response formats for REST apis. The video is available at dzone.com/articles/oci-and-dzone-present-a-grails-quickcast-2.

Another powerful feature supported by the tool is convention based content negotiation. Consider a simple domain class.

package demo

import grails.rest.Resource

@Resource(uri='/books', formats=['json'])
class Book {
    String title
    String author

A simple JSON view for that domain class might look like this.

// grails-app/views/book/_book.gson
import demo.Book

model {
	Book book

json {
   bookTitle book.title
   bookAuthor book.author

When a request is made to render a Book, that view will be used by default.

$ curl http://localhost:8080/books/1.json
{"bookTitle":"Wool","bookAuthor":"Hugh Howey"}

Grails takes into account a number of factors when attempting to resolve the view including the content type, version and locale.

The following paths are searched:

  • view_name[_LOCALE][_ACCEPT_CONTENT_TYPE][_ACCEPT_VERSION].gson (Example: show_de_hal_v1.0.gson)
  • view_name[_LOCALE][_ACCEPT_CONTENT_TYPE].gson (Example: show_de_hal.gson)
  • view_name[_LOCALE][_ACCEPT_VERSION].gson (Example: show_de_v1.0.gson)
  • view_name[_LOCALE].gson (Example: show_de.gson)
  • view_name[_ACCEPT_CONTENT_TYPE][_ACCEPT_VERSION].gson (Example: show_hal_v1.0.gson)
  • view_name[_ACCEPT_VERSION][_ACCEPT_CONTENT_TYPE].gson (Example: show_v1.0_hal.gson)
  • view_name[_ACCEPT_CONTENT_TYPE].gson (Example: show_hal.gson)
  • view_name[_ACCEPT_VERSION].gson (Example: show_v1.0.gson)
  • view_name.gson (Example: show.gson)

The content type (defined by either the ACCEPT header or file extension in the URI) is taken into account to allow different formats for the same view.

For more detail, see the official documentation.

Published on 13 Apr 2016