1

I have my Grails Domain classes annotated with @Resource with the uri specifications in UrlMappings where I declare the resource nesting. But even though according to https://docs.grails.org/latest/guide/theWebLayer.html#restfulMappings it seems that just declaring this the right way, I should have the correct behavior that I wanted, which is that a URL pattern such as /nesting/1/nested will list the nested domain that belonged to the nesting domain with ID 1, the observed behavior is that it just lists out all nested domain objects.

So for that, my workaround is to have a controller implemented that overrides the listResources to filter the nested domain by the nesting domain. But what's weird to me is why I even have to do that at all. The documentation said it defaults to the index action but said index action seems to just behave as if it's the index() of nested (without taking nesting into account).

My domain entities are WeightSensor:

@Resource(formats = ['json', 'xml'])
class WeightSensor extends Sensor<WeightData>
{
    Set<WeightData> data
    static constraints = {
    }
}

its superclass Sensor

@Resource(formats = ['json', 'xml'])
class Sensor<T extends SensorData>
{
  Set<T> data
  static hasMany = [data: SensorData]
  String name

  static constraints = {
    name unique: true
  }
}

and WeightData

class WeightData extends SensorData
{
    Float weight
    static constraints = {
        weight nullable: false
    }
}

and its superclass SensorData

class SensorData
{
  @BindingFormat('yyyy-MM-dd HH:mm:ss.S') // 2019-07-11 22:00:28.909
  Date timestamp

  static belongsTo = [sensor: Sensor]

  static constraints = {
    timestamp nullable: false
  }
}

In my UrlMappings I have the following:

    "/sensor/weight"(resources: 'weightSensor') {
      "/data"(resources: "weightData")
    }

My WeightDataController extends from a SensorDataController:

class WeightDataController extends SensorDataController<WeightSensor, WeightData>
{
  @SuppressWarnings("GroovyUnusedDeclaration")
  static responseFormats = ['json', 'xml']

  WeightDataController()
  {
    super(WeightData, WeightSensor, "weightSensorId")
  }
}

And SensorDataController in turn extends RestfulController, and overrides the listAllResources method as below.

import grails.rest.RestfulController

class SensorDataController<S extends Sensor, T extends SensorData> extends RestfulController<T>
{
  String idProperty
  Class<S> sensorType

  @SuppressWarnings("GroovyUnusedDeclaration")
  static responseFormats = ['json', 'xml']

  protected SensorDataController(Class<T> dataType, Class<S> sensorType, String idProperty)
  {
    super(dataType)
    this.idProperty = idProperty
    this.sensorType = sensorType
  }

  @Override
  protected List<T> listAllResources(Map params)
  {
    Long sensorId = params.get(idProperty) as Long
    if (sensorId)
    {
      resource.withCriteria() {
        eq 'sensor.id', sensorId
        maxResults params.max ?: 10
        firstResult params.offset ?: 0
      } as List<T>
    }
    else
    {
      super.listAllResources(params)
    }
  }
}

Note because in order for me to have my WeightDataController class be used, I needed to remove the @Resource on top of WeightData domain entity above, another nice little gem of wisdom I had to discover with trial and error.

I can probably blame this on the fact that the documentation for nested resources seems a bit open to interpretation. But when we see in the documentation a URL like GET books/${bookId}/authors, doesn't that look like it should return the list of Author objects that belongs to the Book instance IDed by bookId?

I know that I'm not alone as I did find this online of someone asking the same question I have - https://gist.github.com/mnellemann/7cfff1c721ef32f0be6c63574795f795 but no one answered them either. I also came across another SO post nested RESTful resources that was abandoned 5 years ago as well.

But 3 people having the same question and no one responding to our questions (I asked mine on the Grails Slack community) usefully because there is a work-around is not acceptable. At the risk of having my question taken down for a slew of different reasons, I question the usefulness of even having the grails nested resource URL mapping in the first place because I could have done everything manually myself without having to "declare" such a nesting in UrlMappings.

In closing, what I'm trying to find out is whether or not there's more "configuration" I need to do to get Grails nested Resources to behave in the way that I expected, which is how the documentation painted, correctly. Because just doing what was described doesn't get me that.

paulito415
  • 194
  • 1
  • 9

0 Answers0