4

我正在尝试设计一个基于 REST 的 Web 服务来与我正在开发的农场动物管理系统交互。

为了详细解释这个问题,我收集了属于农场的动物。每只动物都有自己的信息 - 例如名称、身份证号、品种年龄等。因此,我假设如下 URI 适合:

/animals               <- retrieve list of animals
/animals/{animal-id}   <- Retrieve only one animal
/animals?breed=sheep   <- Search/query

当我尝试将其他依赖资源链接到每只动物时,问题就出现了。动物可以有一组体重信息,以及我所说的评论(对特定动物的观察)。这些中的每一个都依赖于并且只存在于那个特定的动物,但它们本身就是我想要访问的资源。

IMO 最简单的方法是将资源嵌套在动物 URI 中:

/animals/{animal-id}/weights
/animals/{animal-id}/comments

但是,我认为需要直接访问和查询权重评论,而不参考动物。使用示例是从特定品种的所有动物中检索最近的(或所有)重量,...?breed=sheep甚至返回选择单个动物 ID 的重量/评论...?animals={ID1},{ID2},{...}

当我想一次向多只动物添加一条评论时,会出现进一步的复杂情况。(请原谅我对 POST 和 JSON 的表示)

POST ....
{
  "comment":"Animal moved to paddock B",
  "animals":[{id1}, {id2}, ...]
}

我知道这个问题的明显解决方案是对我想要检索/编辑的每只动物进行 GET 和 POST(例如)。不过,我不希望这样做,因为最终我希望从移动设备访问此服务,因此减少呼叫次数似乎是明智之举。

我相信网络标准允许在 URI 中使用 CSV,所以这样的东西可以工作,

/animals/{id1},{id2},{..}/weights

但是,我预计可能需要一次引用(或查询)十个动物的情况,这将导致混乱和不友好的 URI。

我目前认为的解决方案是将权重评论作为自己的资源公开,这样我就可以直接访问和查询它们

/weights
/weights/{weight-id}
/weights?breed=sheep

甚至直接发布到收藏

POST /comments
{
  "comment":"Animal moved to paddock B",
  "animals":[{id1}, {id2}, ...]
}

但是会/animals/{animal-id}/weights返回什么?它甚至需要,还是我只是引用/weights?animal={animal-id}资源本身的链接?但是可以链接到查询的资源吗?

我是在做一个多余的,还是只是提供“另一种”访问信息的方式?

我做错了什么,是让我的数据库影响我的服务模型,还是我完全错过了重点?

我对此很陌生,并且已经阅读了很多关于这些问题的相互矛盾的论点,因此对于什么最适合我的要求感到很困惑。

谢谢!

4

2 回答 2

3

如果您想这样处理其他实体(等)/weights,最好为其他实体定义顶级资源。/comments然后,您可以批量方式 POST 到这些端点。

POST /comments

{
    "animals" : [
        {"id" : 1},
        {"id" : 2},
        {"id" : 3},
        {"id" : 4},
    ],
    "commentText" : "Sent to Hamburger Hamlet"
}

请注意,在您的 URL 中包含长的 id 列表并不是一个好的设计,原因有很多,包括大多数浏览器和 HTML 代理对 URL 长度有限制(好的经验法则是尝试将 URL 长度保持在 2083 个字符或更少)。

于 2012-12-12T01:47:11.080 回答
1

我也遇到过类似的问题,但最终我们能够通过使用 API 为不同的用户类型设置特定的 url 命名空间(可以这么说)来消除您所遇到的复杂性。

例如,它可能是一个农场工人客户端应用程序,它将执行您所描述的 /weights、/comments 操作(POST、PUT、DELETE 等),因此您可以通过以下方式保持其功能清洁:

/farmworkers/comments
/farmworkers/weights

然后仍然将/animals/{animal-id}/weightsURL 保留在其他一些“命名空间”中。

要考虑的另一件事是使用 HAL 格式 (http://stateless.co/hal_specification.html) 之类的嵌入资源,这可以让您在请求等中嵌入多个动物资源。希望这会有所帮助。

于 2012-12-13T00:46:09.383 回答