RESTful API设计:用于创建多对多关系的PUT或POST?
对于设计和创建RESTful API,会出现以下问题: API支持GET(用于查询)、POST(用于创建)、PUT(用于更新)和DELETE(用于删除) 假设数据库中有一篇文章和一家商店都已经存在 现在我们需要一个rest调用来将article实例链接到shop实例。以下哪种解决方案是最佳/最干净的休息设计:RESTful API设计:用于创建多对多关系的PUT或POST?,api,rest,http,Api,Rest,Http,对于设计和创建RESTful API,会出现以下问题: API支持GET(用于查询)、POST(用于创建)、PUT(用于更新)和DELETE(用于删除) 假设数据库中有一篇文章和一家商店都已经存在 现在我们需要一个rest调用来将article实例链接到shop实例。以下哪种解决方案是最佳/最干净的休息设计: /shop/id/article/id/-->随附邮件 /shop/id/article/id/-->带PUT /shoparticlerelation/-->with POST(主体中带
/shop/id/article/id/
您不能使用它,因为在您想要链接它们的时候,这个端点还不存在(或者至少不应该存在)。应该定义此端点的是将它们链接在一起的操作
/shoparticlerelation/
您不应该使用此选项,因为shoparticlerelation
不是资源/实体。通常在rest中,每个命名的url段都代表一个可以被CRUD-ed的资源。/shops
是一个很好的例子,/articles
也是一个很好的例子,但这个不是
我建议如下: 定义以下端点
/shops
用于发布新店铺/shops/id
用于在单个店铺上操作/articles
用于发布新文章/articles/id
用于对单个项目进行操作
然后,要将它们链接在一起,您可以执行所谓的补丁请求,以更新商店的文章或文章的商店:
PATCH /shops/1 HTTP/1.1
{
"attribute": "articles",
"operation": "add",
"value": "8" // the article id
}
及
根据您的评论,我假设一个文章模型有一个商店列表作为属性,反之亦然,这使得这种方法有效
修补程序请求用于通过指定更新方式和内容来修改现有资源。这与PUT不同,因为PUT将使用请求中的值替换整个资源,但是修补程序仅用于修改(而不是替换)资源。我假设在这种情况下,您已经有了一个
商店集合和一个文章集合,您只希望将两者链接在一起
一个选项是公开一个更像db的“资源”,它表示这个链接,并具有如下操作
POST /shopArticleLinks HTTP/1.1
{ "shop" : xxx,
"article: YYY
}
我个人会把它作为商店和/或更自然的庄园中的物品来展示,比如
PUT /shop/<ID> HTTP/1.1
{ /* existing details */
"articles": [ /* list of articles */ ]
}
PUT/shop/HTTP/1.1
{/*现有详细信息*/
“条款”:[/*条款清单*/]
}
我在这里使用了JSON,但当然要使用您想要使用的格式。我也坚持使用PUT,正如你所说的,但是记住,你应该为新的修改版本发送一个完整的替换,补丁可以用来发送部分更新,但是你需要考虑你想怎么做,可能有点像
PATCH /shops/<ID>/articleLinks HTTP/1.1
{ "add" : [],
"remove : []
}
PATCH/shops//articleLinks HTTP/1.1
{“添加”:[],
“删除:[]
}
不要忘记,服务器端您可以查看被推荐的文章,并确保它们有一个正确的反向指针
其他想法
关于第二种方法,您将链接公开为商店
和/或文章
资源的属性。请记住,这是完全可以接受的(在本例中是相当合适的)当您更新给定商店中的链接时,相应文章中的链接也会更新。简单英语中的文章和商店之间的关系是什么?多个商店和多个文章-每个商店都可以出售每一篇文章,但只有当它被连接时。我为您推荐了+1补丁,但是通过一个操作使用两个请求可以取消该操作。@Coshman我建议了两种方法将它们链接到这里的两个补丁请求。我可能会在同一个请求中同时链接它们,无论您通过哪种资源进行补丁。啊,我明白了,基本上是我建议的,只是没有那么明确。”您不能使用它,因为在您想要链接它们的时候,这个端点还不存在(或者至少不应该存在)。“-这不是一个品味的问题,以及您如何决定何时存在资源关系?在我看来,如果shopid和articleid本身存在,/shops/shopid/articles/articleid也可以始终存在,这似乎是正确的。此资源上的GET在默认情况下可以返回{linked:false}。要在商店中添加或删除一篇文章,PUT可以用来更新链接属性。这听起来是可行的,但是创建一个新的资源来链接另外两个资源是迈向设计模式所谓的“类爆炸”的一步。是的,这绝对不是我会选择的。它确实反映了它最有可能存储在数据库中的方式,但这忽略了REST:P的“代表性”部分
PATCH /shops/<ID>/articleLinks HTTP/1.1
{ "add" : [],
"remove : []
}