JSON in Grails with nested collections

I have totally fallen in love with Grails and Groovy. I am probably the last Java developer in the world to try out Groovy and Grails but it has never been my top priority. So I started to write a little web application for myself, which I will host later on Google App Engine.

One common scenario is that you have nested domain classes. In my case, I have a Show class. A Show is basically a TV series like Lost or Deperate Housewives. Each Show has a list of Season's. These seasons are strictly in order, like Lost has Season 1, 2, 3, 4 and 5 so far. Each Season has a number of Episode's, which are also stricly ordered. Then finally each Episode can be aired in different formats like HDTV, 720p or Standard. This makes up a nice class hierarchie having 1:n relations.




class Show {

String name

static hasMany = [ seasons : Season ]

static mapping = {
table 'ct_show'
}

static constraints = {
name(size:1..100,blank:false)
}
}

class Season {

Integer seasonNumber

static hasMany = [ episodes : Episode ]

static mapping = {
table 'ct_season'
}

static constraints = {
seasonNumber(size:1..100,blank:false)
}
}

class Episode {

Integer episodeNumber

static hasMany = [ formats : Format ]

static mapping = {
table 'ct_episode'
}

static constraints = {
episodeNumber(size:1..100,blank:false)
}
}

class Format {

String name

static mapping = {
table 'ct_format'
}

static constraints = {
name(size:1..100,blank:false)
}
}




Now I had a typical use case, that when you want to use Ajax within you web application, you want the Controller classes to return you domain objects as JSON. In Grails this is easy to accomplish, just read this example. However, I had the big problem that my domain class hierarchy heavily uses nested collections. This will not work when you just do this:



render Season.get(1) as JSON



In this blog post, the last example offers a solution to my problem but it is a rather static example. The idea is to use my root object (Season in my particular case) to produce a JSON string in the format I want and then return it via render as JSON. Building up this String would be quite a big chunk of code in Java probably involving StringBuilder, but Groovy has this great method .collect for Collections. Here is the Groovy code. Try this in Java.



def selectedSeason = Season.get(1)
def seasonJSON = [
id: selectedSeason.id,
seasonNumber: selectedSeason.seasonNumber,
episodes: selectedSeason.episodes.collect{
[
id: it.id,
episodeNumber: it.episodeNumber,
formats: it.formats.collect{
[
id: it.id ,
name: it.name
]
}
]
}
]

render seasonJSON as JSON

1 Kommentare:

The Council hat gesagt…

Hi

This is a quite straightforward and nice to read article. Thanks for sharing your knowledge. It helped me a bit. =)

Greets from Berlin.