restgrailsgrails-orm

Include transient domain class properties as restful json or xml response in grails


I have read numerous ways to try and achieve this, but I would have thought it would be fairly easy?

Given a domain class:

class DomainClassTest{
    String foo
    String bar

    //add accessor
    String getMessage() {
        "Hello"
    }
}

I would like to include the transient property message in both XML and JSON responses.

What is the easiest way to accomplish this?

I have read the documentation on renderers; http://grails.org/doc/latest/guide/single.html#renderers

I have tried the following:

DomainClassTestController.groovy:

class DomainClassTestController extends RestfulController<DomainClassTestController>{
    static responseFormats = ['xml','json']

    DomainClassTestController() {
        super(DomainClassTest)
    }
}

/conf/spring/resources.groovy

beans = {
    xmlDomainClassTestRenderer(XmlRenderer, DomainClassTest) {
        includes = ['message']
    }
    jsonDomainClassTestRenderer(JsonRenderer, DomainClassTest) {
        includes = ['message']
    }
}

Simple enough, but a JSON/XML GET request returns empty.

I find it hard to believer there isn't a simple way to modify the response without using ObjectMarshallers or converters?


Solution

  • I was dealing with this issue as well, and found there is very useful plugin for customizing the marshalling/rendering behavior of Domain objects: "marshallers"

    Be aware that for each Domain with which you use plugin (specifying "marshalling" on the class), it will circumvent anything settings you make in resources.groovy regarding the rendering of your domain. (This is actually a good thing IMHO, as it allows you to keep the rendering details about your Domain class in the same place as the class.)

    So your example Domain class would look like this:

    class DomainClassTest {
      static marshalling = {
        virtual {
            message { value, json -> json.value(value.getMessage()) }
        }
      }
    
      String foo
      String bar
    
      //add accessor
      String getMessage() {
          "Hello"
      }
    }