title: Grails REST API - Render JSON with paging, metadata and custom include fields from params
body: <p>I'm looking for a best way to design a custom JSON response for RESTful API in Grails based on this presentation <a href="http://www.slideshare.net/stormpath/rest-jsonapis" rel="nofollow noreferrer">Design Beautiful REST + JSON APIs</a> by <a href="https://stackoverflow.com/users/407170/les-hazlewood">Les Hazlewood</a>.</p>
  
  <p>Here is my Domain class</p>
  
  <pre><code>class TaxiType {
  
      Date dateCreated, lastUpdated
      String description
      User createdBy
  
      static hasMany = [taxis: Taxi]
  
      static constraints = {
      }
  }
  </code></pre>
  
  <p>The desired response format for list is</p>
  
  <pre><code>{
    "meta": {
      "href": "https://api.mydomain.com/taxi-types",
      "otherData": "..."
    },
    "paging": {
      "offset": 0,
      "limit": 10,
      "total": 100,
      "first": "https://api.mydomain.com/taxi-types?offset=0&amp;limit=10",
      "previous": null,
      "next": "https://api.mydomain.com/taxi-types?offset=90&amp;limit=10",
      "last": "https://api.mydomain.com/taxi-types?offset=90&amp;limit=10"
    },
    "data": [
      {
        "href": "https://api.mydomain.com/taxi-types/1",
        "id": 1,
        "description": "description 1",
        "taxis": {
          "href": "https://api.mydomain.com/taxi-types/1/taxis"
        }
      },
      ...
    ]
  }
  </code></pre>
  
  <p><strong>TaxiTypeController.groovy</strong></p>
  
  <pre><code>def index(Integer limit) {
      params.max = Math.min(limit ?  : 10, 100)
          params.offset = params ? .offset ? .toInteger()
          withFormat {
          json {
              respond TaxiType.list(params),
              [includes : includeFields,
                  paging : [total : TaxiType.count(), limit : params ? .max, offset : params ? .offset ?  : 0]
              ]
          }
      }
  }
  private getIncludeFields() {
      params.fields ? .tokenize(', ')
  }
  </code></pre>
  
  <p><strong>SumoJsonCollectionRenderer.groovy</strong></p>
  
  <pre><code>class SumoJsonCollectionRenderer extends JsonCollectionRenderer {
      SumoJsonCollectionRenderer(Class componentType) {
          super(componentType)
      }
      public SumoJsonCollectionRenderer(Class componentType, MimeType...mimeTypes) {
          super(componentType, mimeTypes)
      }
       @ CompileStatic(SKIP)
       @ Override
      protected void renderJson(object, RenderContext context) {
          log.debug(object)
          log.debug(object.size())
          log.debug(object.getTotalCount())
          Map tObject = ['data' : object]
          if (context.arguments ? .paging) {
              tObject['paging'] = context ? .arguments ? .paging
          }
          super.renderJson(tObject, context)
      }
  }
  </code></pre>
  
  <p>Required features are:</p>
  
  <p><strong>1) API users should be able to get only the required fields (Partial representations)</strong></p>
  
  <pre><code>GET https://api.mydomain.com/taxi-types??fields=id,description,taxis
  </code></pre>
  
  <p>the desired response for this request should be</p>
  
  <pre><code>{
      "meta" : {...}
      "paging" : {...}
      "data" : [{
              "href" : "https://api.mydomain.com/taxi-types/1",
              "id" : 1,
              "description" : "Taxi Type1",
              "taxis" : [{
                      "href" : "https://api.mydomain.com/taxis/123"
                  },
                  ...
              ]
          },
          ...
      ]
  }
  </code></pre>
  
  <p>What I'm getting was</p>
  
  <pre><code>{
      "data" : [{
              "id" : 1,
              "description" : "Taxi Type1",
              "taxis" : [{
                      "class" : "com.domain.project.Taxi",
                      "id" : 1
                  }
              ]
          },
          ...
      ],
      "paging" : {
          "total" : 80,
          "limit" : 10,
          "offset" : 0
      }
  }
  </code></pre>
  
  <p>I referred answer to this question <a href="https://stackoverflow.com/questions/23940641/render-metadata-for-pagination-from-grails-restfulcontroller-index-search-action">Render metadata for pagination from Grails RestfulController index/search actions</a>.</p>
  
  <p>But still need to include links for <code>first, previous, next &amp; last</code> in paging as mentioned in the desired format above.</p>
  
  <p><strong>2) Customizing output</strong></p>
  
  <p>for example 
  the <code>taxis</code> property with <code>hasMany</code> relationship should be rendered by default as</p>
  
  <pre><code>"taxis": {
      "href": "https://api.mydomain.com/taxis/12345"
  }
  </code></pre>
  
  <p>and if the user prefer to expand <code>taxis</code> property, for eg: <code>GET /taxi-types?expand=taxis</code>, the JSON format should be</p>
  
  <pre><code>"taxis": {
      "href": "https://api.mydomain.com/taxis/12345"
      "name": "Taxi name",
      "type": "https://api.mydomain.com/taxi-types/1"
      ...
  }
  </code></pre>
  
  <p><strong>3) Add <code>meta</code> object to all responses</strong></p>
  
  <pre><code>"meta": {
       "href": "https://api.mydomain.com/taxi-types",
       ...
  }
  </code></pre>
  
  <p>I tried Json Marshaller to customize the response. Here is my Marshaller code</p>
  
  <pre><code>JSON.registerObjectMarshaller(TaxiType) {TaxiType taxiType-&gt;
      return [
          id : taxiType ? .id,
          description : taxiType ? .description
      ]
  }
  </code></pre>
  
  <p>but it always renders with those two properties in return array <code>id &amp; description</code>, even if I want some other properties like <code>taxis</code>.</p>
  
  <p>How above 3 requirements can be implemented?. Thanks in advance.</p>