我正在尝试关注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中?
答案 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上下文中的另一个资源(在业务逻辑的上下文中,这是另一个故事)。
我已经使用过这个策略,但在向现有端点添加新功能和添加新端点时,它仍然会让我感到惊讶。