嵌套关系是否应反映在JSON API的URL中?

时间:2017-08-08 17:43:11

标签: json-api

我正在尝试关注JSON API。我需要公开对嵌套资源的CRUD访问:产品评论。

在使用JSON API之前,我希望有一个这样的REST接口:

GET    /products/:product_id/reviews     - list reviews for a product
POST   /products/:product_id/reviews     - add a review for a product
PATCH  /products/:product_id/reviews/:id - update a review for a product
DELETE /products/:product_id/reviews/:id - delete a review for a product

我看到一些像in the spec这样的嵌套结构:

  

例如,照片评论的网址为:

     

/photos/1/comments

但我不确定这个结构是否适合所有行动。

一方面,如果我要在评论数据POST /products/:product_id/reviews下的POST正文中指定产品,relationships创建似乎是多余的。

另一方面,如果在删除评论时指定产品ID很有用(可能不是),DELETE /products/:product_id/reviews/:id似乎是唯一理智的方法; people argue about whether a request body is even allowed for DELETE requests

我可以为某些请求而不是其他请求嵌套:

GET    /products/:product_id/reviews  - list reviews for a product
POST   /products/:product_id/reviews  - add a review for a product
PATCH  /reviews/:id                   - update a review
DELETE /reviews/:id                   - delete a review

但这似乎很奇怪。

我永远无法筑巢:

GET    /reviews     - list reviews for the product specified in params
POST   /reviews     - add a review for the product specified in params
PATCH  /reviews/:id - update a review
DELETE /reviews/:id - delete a review

但这看起来很尴尬,似乎与我从文档中提出的第一句话不符。

使用JSON API时,嵌套资源关系是否应反映在URL中?

1 个答案:

答案 0 :(得分:11)

我真的很喜欢你的问题,因为我一直有同样的想法。我很困惑,还没有人留下答案。

我一直在生产系统上使用JSON API一年多,我想给我两分钱。

首先,当我启动将要使用JSON API的项目时,我对嵌套与非嵌套资源存在疑问。然后,我遇到了嵌套资源的问题,这些资源本来可以通过非嵌套资源来避免。

要采用与示例中相同的路径,请考虑GET /products/:product_id/reviews端点。 如果这样做,将评论嵌套在产品下是非常有意义的,因为我们最初在产品的上下文中显示评论。一切都很好。

我们后来想在前端构建一个页面,显示用户和用户创作的所有评论。 虽然我们已经有了获得评论的终点,但我们必须建立一个新的,例如GET /users/:id/reviews

如果我们只是将GET /reviews上的第一个端点放在?filter[product_id]=:id的过滤器上,我们就可以向该端点添加一个新过滤器,这对IMO来说很有意义。

我确实使用嵌套资源,但仅限于GET /users/:id/email_settings这样的单例资源以及其他一些有意义的特殊情况。

根据我的经验,如果将每种资源视为独立于其他资源,则将来会更容易。资源之间存在资源和关系。没有资源“拥有”API上下文中的另一个资源(在业务逻辑的上下文中,这是另一个故事)。

我已经使用过这个策略,但在向现有端点添加新功能和添加新端点时,它仍然会让我感到惊讶。