REST-ish用于多个依赖资源的URI设计

时间:2012-12-12 01:39:59

标签: web-services api rest

我正在尝试设计一个基于REST-ish的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},{...}返回权重/评论。 / p>

当我想一次向多个动物添加一条评论时,会出现更多复杂情况。 (请原谅我对POST和JSON的陈述)

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

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

我相信网络标准允许在URI中使用CSV,因此这样的事情可以起作用,

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

但是,我期待一次(或查询)需要引用十(10)只动物的情况,这会导致一个混乱且不友好的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}资源本身的链接?但链接到查询资源是否可以?

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

有什么我做错了,我让我的数据库影响我的服务模式,还是我完全忽略了这一点?

我对此很陌生,并且已经阅读了很多关于这些问题的矛盾论点,所以对于什么对我的要求最好是很困惑。

谢谢!

2 个答案:

答案 0 :(得分:3)

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

POST /comments

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

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

答案 1 :(得分:1)

我遇到了类似的问题,但最终我们能够通过使用API​​为不同的用户类型提供特定的URL名称空间(可以这么说)来消除您所获得的复杂性。

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

/farmworkers/comments
/farmworkers/weights

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

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