Master/Detail 使用 REST
Master/Detail with REST
我敢肯定这个话题之前一定已经被讨论过了,所以我很高兴有人指出我在搜索时可能遗漏的任何文章等。
我需要实现一个非常简单的 REST API 来添加和检索 master/detail 关系中的记录。我的两个选项如下:
选项 1
POST /master
POST /master/[id]/details
GET /master/[id]
GET /master/[id]/details
优点
- 感觉更多'RESTful'
- 可以检索细粒度数据以提高性能
缺点
- 大师没有至少一个细节是没有意义的。如何处理原子性?如果在添加细节时失败,是否在母版上补偿 DELETE?
- 检索 master/detail 集合需要多次调用
选项 2
POST /master_and_details
GET /master_and_details/[master id]
优点
- 易于管理原子性
缺点
- 需要管理的结构更复杂
- GET 必须 return 整个结构(并不总是有效)
- 感觉不是很'RESTful'
谢谢,
约翰
REST 或多或少决定了选项 1,选项 2 只是一个普通的旧 http api。
你说大师没有至少一个细节就没有意义的说法可能是错误的。您不知道聪明的开发人员将来会如何使用您的 api。你可以猜,但你不一定真的知道。
如果您自己确实需要复合解决方案,您总是可以在更高级别添加一个接口来调用两个单独的接口和 returns 一个复合对象。
选项 1 允许微服务实现的可能性——或者至少,将关注点分离到两个可分离的对象中。仅选项 2 不会。
至少为了争论,并且冒着我微薄的声誉的风险,我会尝试第三种方法。
您将拥有两种资源:主要资源和详细信息。 (不是“细节”,除非你想完全复数,在这种情况下你会有“大师”和“细节”)。 master 的表示将包括详细信息的集合,或者(更好)link 与详细信息的关系。考虑 https://www.rfc-editor.org/rfc/rfc6573 的 link 关系。
因此 master 的 GET 包括(直接或间接通过关系)详细信息的集合。 POST/PUT of master 还可以 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 吗?我会说是的。
如果 detail 使用复合键,则不能独立于 master 获取它,因此无法支持上面显示的第一种形式。此外,{detailKey},如上面最后一个示例中所使用的,将是主项中详细信息项的标识符(通常是序列号)。
我肯定会选择 选项 1,因为 选项 2 与 REST 无关。但这并不意味着您需要使用多个查询来获取 Master
+ Detail
.
由于 Detail
属于 Master
(因此它是其中的一部分),在我看来 return Master
和 Detail
绝对没问题, 当查询 Master
.
您也可以考虑使用参数来控制是否发送 Detail
。
因此,您可以使用 GET /master/1?detail=true
.
而不是执行 GET /master/1
对于 POST
和 PUT
大致相同。只是没有查询参数,您的正文中有一个关于 Detail
的 "section"。
使用 JSON 的示例:
{
"data": {
"name": "master",
"detail": [
{
"name": "detail1"
},
{
"name": "detail2"
}
]
}
}
具有此数据的 POST
可以创建具有 name
"master" 的 Master
和此 Master
的 2 Detail
。
如@ElroyFlynn 之前所述,Detail
也可以在没有 Master
的情况下访问,如果这有意义的话。
想想一个有 Thread
s 和 Post
s 的论坛。通常 Thread
是 Master
,每个 Post
是 Detail
。但是如果你想搜索最近一小时的所有Post
s,你肯定想直接查询帖子(查询可能类似于GET /post?max_age=1h
)。
我也不同意,没有 Detail
的 Master
没有意义。可能在某些情况下没有,但在论坛的情况下,Thread
本身就有意义。
对于 atomicity
:
这取决于具体情况:如果删除 User
,通常会保留他的 Post
(即使在 Whosebug 上也是如此)。如果你改为删除 Thread
,我想你可以删除 Post
s 到.
我敢肯定这个话题之前一定已经被讨论过了,所以我很高兴有人指出我在搜索时可能遗漏的任何文章等。
我需要实现一个非常简单的 REST API 来添加和检索 master/detail 关系中的记录。我的两个选项如下:
选项 1
POST /master
POST /master/[id]/details
GET /master/[id]
GET /master/[id]/details
优点
- 感觉更多'RESTful'
- 可以检索细粒度数据以提高性能
缺点
- 大师没有至少一个细节是没有意义的。如何处理原子性?如果在添加细节时失败,是否在母版上补偿 DELETE?
- 检索 master/detail 集合需要多次调用
选项 2
POST /master_and_details
GET /master_and_details/[master id]
优点
- 易于管理原子性
缺点
- 需要管理的结构更复杂
- GET 必须 return 整个结构(并不总是有效)
- 感觉不是很'RESTful'
谢谢, 约翰
REST 或多或少决定了选项 1,选项 2 只是一个普通的旧 http api。
你说大师没有至少一个细节就没有意义的说法可能是错误的。您不知道聪明的开发人员将来会如何使用您的 api。你可以猜,但你不一定真的知道。
如果您自己确实需要复合解决方案,您总是可以在更高级别添加一个接口来调用两个单独的接口和 returns 一个复合对象。
选项 1 允许微服务实现的可能性——或者至少,将关注点分离到两个可分离的对象中。仅选项 2 不会。
至少为了争论,并且冒着我微薄的声誉的风险,我会尝试第三种方法。
您将拥有两种资源:主要资源和详细信息。 (不是“细节”,除非你想完全复数,在这种情况下你会有“大师”和“细节”)。 master 的表示将包括详细信息的集合,或者(更好)link 与详细信息的关系。考虑 https://www.rfc-editor.org/rfc/rfc6573 的 link 关系。
因此 master 的 GET 包括(直接或间接通过关系)详细信息的集合。 POST/PUT of master 还可以 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 吗?我会说是的。
如果 detail 使用复合键,则不能独立于 master 获取它,因此无法支持上面显示的第一种形式。此外,{detailKey},如上面最后一个示例中所使用的,将是主项中详细信息项的标识符(通常是序列号)。
我肯定会选择 选项 1,因为 选项 2 与 REST 无关。但这并不意味着您需要使用多个查询来获取 Master
+ Detail
.
由于 Detail
属于 Master
(因此它是其中的一部分),在我看来 return Master
和 Detail
绝对没问题, 当查询 Master
.
您也可以考虑使用参数来控制是否发送 Detail
。
因此,您可以使用 GET /master/1?detail=true
.
而不是执行 GET /master/1
对于 POST
和 PUT
大致相同。只是没有查询参数,您的正文中有一个关于 Detail
的 "section"。
使用 JSON 的示例:
{
"data": {
"name": "master",
"detail": [
{
"name": "detail1"
},
{
"name": "detail2"
}
]
}
}
具有此数据的 POST
可以创建具有 name
"master" 的 Master
和此 Master
的 2 Detail
。
如@ElroyFlynn 之前所述,Detail
也可以在没有 Master
的情况下访问,如果这有意义的话。
想想一个有 Thread
s 和 Post
s 的论坛。通常 Thread
是 Master
,每个 Post
是 Detail
。但是如果你想搜索最近一小时的所有Post
s,你肯定想直接查询帖子(查询可能类似于GET /post?max_age=1h
)。
我也不同意,没有 Detail
的 Master
没有意义。可能在某些情况下没有,但在论坛的情况下,Thread
本身就有意义。
对于 atomicity
:
这取决于具体情况:如果删除 User
,通常会保留他的 Post
(即使在 Whosebug 上也是如此)。如果你改为删除 Thread
,我想你可以删除 Post
s 到.