我确定此主题必须已被覆盖,所以我很高兴能够指出我在搜索时可能遗漏的任何文章等。
我需要实现一个非常简单的REST API来添加和检索主/明细关系中的记录。我的两个选项如下:
选项1
POST /master
POST /master/[id]/details
GET /master/[id]
GET /master/[id]/details
赞成
CONS
选项2
POST /master_and_details
GET /master_and_details/[master id]
赞成
CONS
谢谢, 约翰
答案 0 :(得分:2)
REST或多或少地决定了选项1,选项2只是一个普通的旧的api。
如果没有至少一个细节,主人没有意义的声明可能是错误的。你不知道聪明的开发人员将来如何使用你的api。你可以猜,但你真的不知道。
如果你真的需要自己的复合解决方案,你总是可以在更高级别添加一个接口,调用两个独立的接口并返回一个复合对象。
选项1允许微服务实现的可能性 - 或者至少将关注点分离为两个可分离的对象。仅选项2不会。
答案 1 :(得分:2)
至少为了争论,冒着我微薄的声誉,我会尝试第三种方法。
你有两个资源:主人和细节。 (不是“细节”,除非你想完全复数,在这种情况下你会有“主人”和“细节”)。主人的表示将包括细节的集合,或(更好)与细节的链接关系。考虑http://tools.ietf.org/html/rfc6573该链接关系。
因此,主人的GET包括(直接或间接通过关系)细节的集合。主人的POST / PUT也可以通过他们在表单数据中的存在来POST / PUT详细信息成员。
任何细节也可以独立于主人进行GET / PUT / POSTED。在这里,设计在某种程度上取决于细节是否具有自己的主键,而使用复合键与其主键。如果它有自己的主键,那么你可以:
GET /detail/{detailKey} - gets specific detail
POST /detail - creates new detail
GET /master/{masterkey}/detail -- gets all details for master
GET /master{masterkey}/detail/{detailkey} -- get specific detail
显然,在POST上,数据必须包含master的密钥。
您会看到有多个URI可用于获取详细信息。我不认为那是错的,但它确实引入了一些含糊之处:如果detailKey实际上不是masterKey的孩子,那么你是404吗?我会说是的。
如果详细信息使用复合键,则无法独立于主设备进行GET,因此无法支持上面显示的第一个表单。此外,上面最后一个示例中使用的{detailKey}将是主服务器中详细信息项的标识符(通常是序列号)。
答案 2 :(得分:0)
我肯定会选择选项1 ,因为选项2 与REST无关。但这并不意味着您需要使用多个查询来获取Master
+ Detail
。
由于Detail
属于Master
(因此它是其中的一部分),我认为在查询时Master
和Detail
完全可以。 Master
。
您也可以考虑使用参数来控制是否发送Detail
因此,您可以使用GET /master/1
而不是执行GET /master/1?detail=true
对于POST
和PUT
或多或少,同样可行。只是没有查询参数,你有一个"部分"关于Detail
。
使用JSON的示例:
{
"data": {
"name": "master",
"detail": [
{
"name": "detail1"
},
{
"name": "detail2"
}
]
}
}
包含此数据的POST
可以使用Master
" master"创建name
和Detail
的2 Master
s。
正如@ElroyFlynn之前所述,Detail
也可以在没有Master
的情况下访问,如果这样做的话。
想想有Thread
和Post
的论坛。通常,Thread
为Master
,每Post
为Detail
。但是如果你想搜索过去一小时的所有Post
,你肯定想直接查询帖子(查询可能类似于GET /post?max_age=1h
)。
另外,我不同意,Master
没有Detail
的情况不会发生。可能会出现这样的情况,但是在论坛的情况下,Thread
就自己提出了这种情况。
对于atomicity
:
这取决于具体情况:如果删除User
,通常会保留Post
s(即使在StackOverflow上)。如果您改为删除Thread
,我猜您可以将Post
删除为。