Ожидаемое поведение по умолчанию для отображения Grails RESTful на вложенные ресурсы - PullRequest
1 голос
/ 08 октября 2019

Мои классы Grails Domain помечены @Resource со спецификациями uri в UrlMappings, где я объявляю вложение ресурса. Но даже несмотря на то, что согласно https://docs.grails.org/latest/guide/theWebLayer.html#restfulMappings кажется, что просто объявив это правильно, я должен получить правильное поведение, которое я хотел, а именно, что шаблон URL, такой как /nesting/1/nested, перечислит домен nested, которыйпринадлежал домену nesting с идентификатором 1, наблюдаемое поведение состоит в том, что он просто перечисляет все nested объекты домена.

Итак, для этого мой обходной путь должен иметь реализованный контроллер, который переопределяетlistResources для фильтрации домена nested по домену nesting. Но что странно для меня, так это то, почему я вообще должен это делать. В документации сказано, что по умолчанию это действие index, но сказано, что действие index, похоже, ведет себя так, как будто это index () nested (без учета nesting).

Объектами моего домена являются WeightSensor:

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

его суперкласс Sensor

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

  static constraints = {
    name unique: true
  }
}

и WeightData

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

и его суперкласс 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
  }
}

В моем UrlMappings у меня есть следующее:

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

Мой WeightDataController простирается от SensorDataController:

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

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

И SensorDataController, в свою очередь, расширяет RestfulController и переопределяет метод listAllResources, как показано ниже.

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)
    }
  }
}

Примечание, поскольку для того, чтобы использовать мой класс WeightDataController, мне нужно было удалить@Resource поверх WeightData сущности домена выше, еще один приятный маленький камень мудрости, который я должен был обнаружить методом проб и ошибок.

Я, вероятно, могу винить в этом тот факт, что документация для вложенных ресурсов кажетсянемного открыт для интерпретации. Но когда мы видим в документации URL-адрес, такой как GET books / $ {bookId} / авторы, разве это не похоже на то, что он должен возвращать список объектов Author, принадлежащих экземпляру Book, идентифицированному bookId?

Я знаю, что я не одинок, так как нашел в Интернете кого-то, кто задавал тот же вопрос, что и у меня - https://gist.github.com/mnellemann/7cfff1c721ef32f0be6c63574795f795, но никто также не ответил на них. Я также натолкнулся на еще одно SO * сообщение вложенных ресурсов RESTful , которое также было заброшено 5 лет назад.

Но 3 человека, имеющих один и тот же вопрос, и никто не отвечал на наши вопросы (я задал свой вопрос в сообществе Grails Slack), потому что обходные пути неприемлемы. Риск того, что мой вопрос будет рассмотрен по целому ряду причин, я ставлю под сомнение полезность даже того, чтобы в первую очередь отображать URL-адрес вложенного ресурса grails, потому что я мог бы сам все сделать вручную без необходимости «объявлять» такое вложениев UrlMappings.

В заключение я пытаюсь выяснить, есть ли еще «конфигурация», которую мне нужно сделать, чтобы заставить вложенные ресурсы Grails вести себя так, как я ожидал, - так нарисовала документация. правильно. Потому что только то, что было описано, не дает мне этого.

...