嵌套式RESTful资源

6

我正在使用Grails 2.3引入的REST支持。我的应用程序包括以下领域类:

@Resource(formats=['json', 'xml'])
class Sensor {
    String name
    static hasMany = [metrics: Metric]
}

@Resource(formats=['json', 'xml'])
class Metric {

    String name
    String value

    static belongsTo = [sensor: Sensor]
}

UrlMappings.groovy中,我定义了以下嵌套的RESTful URL映射:

"/api/sensors"(resources: 'sensor') {
    "/metrics"(resources: "metric")
}

如果我访问URL /api/sensors/1/metrics,我期望响应能够显示所有与ID为1的Sensor相关联的Metric实例,但事实上它返回了所有Metric实例(最多10个)。
  • 是否有一个URL可以只返回与特定Sensor实例相关联的Metric实例(而不用自己实现控制器)?
  • 是否有一种方法可以覆盖默认的10个结果限制(而无需向请求添加max参数)?

关于在使用资源时更改限制的问题,答案是否定的。这个问题已经在此之前进行了讨论。这个设计选择背后的理由是Resource旨在快速和简便,生成和修改控制器是下一级别的定制化。我之前的回答中有指向Grails源代码的指针,以证明Resource不允许此类定制化。 - Joshua Moore
http://stackoverflow.com/questions/22336804/change-default-for-max-attribute-on-results-for-resource-on-domain-classes-for/22337550#22337550 - Joshua Moore
@JoshuaMoore 谢谢,你知道是否可以获取单个 Sensor 实例的 Metric 实例吗? - Dónal
从未使用过它们,但根据文档:http://grails.org/doc/2.3.x/guide/single.html#restfulMappings,这似乎是您所拥有的。 - Joshua Moore
如果提供的答案有更好的方法,请告诉我。 :) - dmahapatro
@dmahapatro 我认为扩展 RestufulController 并重写 queryForResource 可能会稍微好一些。http://grails.org/doc/latest/guide/webServices.html#extendingRestfulController - Dónal
1个回答

6

看起来并不是那么简单。 :) 如果运行此命令,我们可以得到一个生动的图像:

grails url-mapping-report

查看

Controller: metric
 |   GET    | /api/sensors/${sensorId}/metrics           | Action: index  |
 |   GET    | /api/sensors/${sensorId}/metrics/create    | Action: create |
 |   POST   | /api/sensors/${sensorId}/metrics           | Action: save   |
 |   GET    | /api/sensors/${sensorId}/metrics/${id}     | Action: show   |
 |   GET    | /api/sensors/${sensorId}/metrics/${id}/edit| Action: edit   |
 |   PUT    | /api/sensors/${sensorId}/metrics/${id}     | Action: update |
 |  DELETE  | /api/sensors/${sensorId}/metrics/${id}     | Action: delete |

因此,我们至少需要一个继承RestfulController的MetricController,并覆盖index()方法来对Metric进行额外的检查,并根据Sensor返回列表,如下所示:
class MetricController extends RestfulController<Metric> {
    static responseFormats = ['json', 'xml']

    MetricController() {
        super(Metric)
    }

    @Override
    def index() {
        def sensorId = params.sensorId
        respond Metric.where {
            sensor.id == sensorId
        }.list()
    }
}

当访问/api/sensors/1/metrics时,以上更改将提供预期结果(包括对分页结果的限制)。

这是最简洁的方法吗?为什么这不是默认功能呢?._. - Magic Octopus Urn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接