compile 'org.grails.plugins:views-json:1.0.0' // or whatever is the latest version
10.9 JSON Views
Version: 3.3.0
Table of Contents
10.9 JSON Views
As mentioned in the previous section the REST profile by default uses JSON views to render JSON responses. These play a similar role to GSP, but instead are optimized for outputing JSON responses instead of HTML.
You can continue to separate your application in terms of MVC, with the logic of your application residing in controllers and services, whilst view related matters are handled by JSON views.
JSON views also provide the flexibility to easily customize the JSON presented to clients without having to resort to relatively complex marshalling libraries like Jackson or Grails' marshaller API.
Since Grails 3.1, JSON views are considered by the Grails team the best way to present JSON output for the client, the section on writing custom marshallers has been removed from the user guide. If you are looking for information on that topic, see the Grails 3.0.x guide. |
10.9.1 Getting Started
If you are using the REST or AngularJS profiles then the JSON views plugin will already be included and you can skip the remainder of this section. Otherwise you will need to modify your build.gradle
to include the necessary plugin to activate JSON views:
The source code repository for JSON views can be found on Github if you are looking for more documentation and contributions |
In order to compile JSON views for production deployment you should also activate the Gradle plugin by first modifying the buildscript
block:
buildscript {
...
dependencies {
...
classpath "org.grails.plugins:views-gradle:1.0.0"
}
}
Then apply the org.grails.plugins.views-json
Gradle plugin after any Grails core gradle plugins:
...
apply plugin: "org.grails.grails-web"
apply plugin: "org.grails.plugins.views-json"
This will add a compileGsonViews
task to Gradle, which is invoked prior to creating the production JAR or WAR file.
10.9.2 Creating JSON Views
JSON views go into the grails-app/views
directory and end with the .gson
suffix. They are regular Groovy scripts and can be opened in any Groovy editor.
Example JSON view:
json.person {
name "bob"
}
To open them in the Groovy editor in Intellij IDEA, double click on the file and when asked which file to associate it with, choose "Groovy" |
The above JSON view produces:
{"person":{"name":"bob"}}
There is an implicit json
variable which is an instance of StreamingJsonBuilder.
Example usages:
json(1,2,3) == "[1,2,3]"
json { name "Bob" } == '{"name":"Bob"}'
json([1,2,3]) { n it } == '[{"n":1},{"n":2},{"n":3}]'
Refer to the API documentation on StreamingJsonBuilder for more information about what is possible.
10.9.3 JSON View Templates
You can define templates starting with underscore _
. For example given the following template called _person.gson
:
model {
Person person
}
json {
name person.name
age person.age
}
You can render it with a view as follows:
model {
Family family
}
json {
name family.father.name
age family.father.age
oldestChild g.render(template:"person", model:[person: family.children.max { Person p -> p.age } ])
children g.render(template:"person", collection: family.children, var:'person')
}
Alternatively for a more concise way to invoke templates, using the tmpl variable:
model {
Family family
}
json {
name family.father.name
age family.father.age
oldestChild tmpl.person( family.children.max { Person p -> p.age } ] )
children tmpl.person( family.children )
}
10.9.4 Rendering Domain Classes with JSON Views
Typically your model may involve one or many domain instances. JSON views provide a render method for rendering these.
For example given the following domain class:
class Book {
String title
}
And the following template:
model {
Book book
}
json g.render(book)
The resulting output is:
{id:1, title:"The Stand"}
You can customize the rendering by including or excluding properties:
json g.render(book, [includes:['title']])
Or by providing a closure to add additional JSON output:
json g.render(book) {
pages 1000
}
10.9.5 JSON Views by Convention
There are a few useful conventions you can follow when creating JSON views. For example if you have a domain class called Book
, then creating a template located at grails-app/views/book/_book.gson
and using the respond method will result in rendering the template:
def show(Long id) {
respond Book.get(id)
}
In addition if an error occurs during validation by default Grails will try to render a template called grails-app/views/book/_errors.gson
, otherwise it will try to render grails-app/views/errors/_errors.gson
if the former doesn’t exist.
This is useful because when persisting objects you can respond
with validation errors to render these aforementioned templates:
@Transactional
def save(Book book) {
if (book.hasErrors()) {
transactionStatus.setRollbackOnly()
respond book.errors
}
else {
// valid object
}
}
If a validation error occurs in the above example the grails-app/views/book/_errors.gson
template will be rendered.
For more information on JSON views (and Markup views), see the JSON Views user guide.