Grails benefits from comprehensive out-of-the-box implementations for rendering JSON and XML data, when coupled with some Groovy syntactic sugar, developers are capable of generating JSON or XML data from a structure as simply as:

def json = someInstance as grails.converters.JSON
def xml  = someInstance as grails.converters.XML

However, we may quickly find that we have a little too much data in the response, or we even want to provide data at compile time (without storing it transiently in a domain class as I have done in the example below).

package com.krslynx.foo.bar.mg

class Player {
	
    String alias
    Integer killPoints
    Integer gamePoints

    Integer totalPoints() {
        return killPoints + gamePoints
    }
	
    /** data not to be stored by Hibernate */
    static transients = [
        totalPoints
    ]
}

The above, using the Grails JSON converter would yield (130 char):

{"playerId": 1, "class": "com.krslynx.foo.bar.mg.Player", "alias": "krslynx", "killPoints": 1, "gamePoints": 0, "totalPoints:" 1}

However, as we begin to develop RESTFul services where we may (most probably will!) require both low-latency and high-throughput, we’ll need to reduce the size of our responses, and often, only respond with data that is absolutely required (and to really be RESTFul…)

To tackle this across some larger services developed in Groovy/Grails I’ve adopted quite a pleasent design-pattern, which utilizes the existing JSON and XML converters in Grails.

class Player {
	
    /* .. Truncated .. */
	
    /** This map stores what we will want to render in JSON/XML responses */
    def marshaller = [
        alias: alias,
        totalPoints: totalPoints
    ]
}

During the BootStrap of the application, we may associate all Marshallers we’ve defined for classes we’ve constructed.

def domains = [
    new Player(),
    new Foo(),
    new Bar() // and so on...
]
 
def setupMarshallers(domains, Converter) {
    domains.each { domain ->
        Converter.registerObjectMarshaller(domain.class) { obj ->
            try {
                return obj?.marshaller
            } catch (MissingPropertyException mpe) {
                // as we've above implied it should have a marsahller, handle this as you wish.
                log.warn("Class ${obj.class} does not have a marshaller; please investigate.")
            }
            return obj.properties
        }
    }
}

// Example Usage:
// setupMarshallers(domains, grails.converters.JSON)
// setupMarshallers(domains, grails.converters.XML)

We are then presented with a single entry-point for setting up all marshalling in our application, allowing for more customized responses in both JSON and XML. Similarly, we have an entry-point for any other manipulations to reduce response sizes.

def setupMarshallers(domains, Converter) {
    domains.each { domain ->
        Converter.registerObjectMarshaller(domain.class) { obj ->
            /* .. Truncated .. */
            return obj.properties.minus(obj.properties.findAll { it.value == null }) // remove all members that are null
        }
    }
}

The above is achievable using the transformation minus on the properties map, finding all objects that are null. Of course the amount of transformations you can do here are endless; for example not rendering database identifiers for referenced objects or class name we can use a regular expression or match in the findAll closure

findAll { it.key ==~ /(.*)Id/ }
findAll { it.key.equals("class") }

Furthermore, using the optional marshaller member we can instead marshal according to our own exact needs. Using some of the above, we’re presented with a much more concise (39 char) response which we define in code (which is also great for generating our REST documentation, but I’ll leave that for another post). Using GZip, we can minify this further however we must be mindful of the time complexity of decompression versus the size of the data (afterall we’re often trying to achieve lower-latency, and higher through-put)

{"alias": "krslynx", "totalPoints:" 1}