I'm working with gson and web profile.
My domain is:
package json
import grails.rest.*
@Resource(readOnly = false, formats = ['json', 'xml'])
class Hero {
String name
String data
String relation
Book book
static hasMany = [children: Hero]
My controller is:
package json
import grails.rest.*
import grails.converters.*
class HeroController extends RestfulController {
static responseFormats = ['json', 'xml']
HeroController() {
super(Hero)
}
def show(Hero hero){
respond hero
}
}
My gson:
hero.gson
import json.Hero
model {
Hero hero
}
json tmpl.hero(hero)
_hero.gson
import json.Hero
model {
Hero hero
}
json {
//data hero.data
id hero.id
data(relation: hero.relation)
name hero.name
children g.render(hero.children)
}
If I run it with restful profile then the all children nodes are rendered correctly. If I use web profile only two levels deep are rendered.
My expected result is:
{
"id": 4,
"data": {
"relation": "e"
},
"name": "e",
"children": [{
"id": 2,
"data": {
"relation": "c"
},
"name": "c",
"children": [{
"id": 1,
"data": {
"relation": "b"
},
"name": "b",
"children": []
}
]
}
Is it possible to do one to many json rendering (as with the restful profile)? Is there a way to control depth of the rendering?
P.S. I read the documentation and this part is not very clearfor me:
If you wish for the author to be included as part of the rendering, there are two requirements, first you must make sure the association is initialized.
If the render method encounters a proxy, it will not traverse into the relationship to avoid N+1 query performance problems. The same applies to one-to-many collection associations. If the association has not been initialized the render method will not traverse through the collection!
So you must make sure your query uses a join:
Book.findByTitle("The Stand", [fetch:[author:"join"]])
Secondly when calling the render method you should pass the deep argument:
json g.render(book, [deep:true])
yes it's possible to render your json using web profile. I can do it by adding to build.gradle:
apply plugin:"org.grails.plugins.views-json"
dependencies {
compile "org.grails.plugins:views-json"
compile "org.grails.plugins:views-json-templates"
bootRun {
jvmArgs('-Dspring.output.ansi.enabled=always')
addResources = true
}
and using your code with a little change in the domain class: children lazy: false
@Resource(readOnly = false, formats = ['json', 'xml'])
class Hero {
String name
String data
String relation
//Book book
static hasMany = [children: Hero]
static mapping = {
children lazy: false
}
Which will change the fetch mode. You can consult about fetching here:
enter link description herehttp://docs.grails.org/3.1.1/ref/Database%20Mapping/fetch.html