根据变量值设计具有不同请求主体的 API
Design for API with Different requestBody based on variable value
我有一个 REST API uploadFeed 上传基于 feedType 的用户提要(字符串值作为请求正文的一部分输入)。不同的 feedtype 在请求正文中提供了不同的 pojo 模型。
例如,如果 feedType 是 "TYPE1",那么 API 的请求正文应该如下所示:
{
"feedType":"TYPE1",
"inputModel": {
"a": "somevalue"
"b" : "somevalue",
"c" : "somevalue",
}
}
如果 feedType 是 "TYPE2",那么 API 的请求正文应该如下所示:
{
"feedType":"TYPE2",
"inputModel": {
"x": "somevalue"
"y" : "somevalue",
"z" : "somevalue",
}
}
什么是最好的API uploadFeed 的设计API。我正在考虑两种可能的解决方案:
解决方案建议 1:有两个不同的 API 端点。
API feedType == Type1 的 URI:/uploadFeed/feedType/{Type1}。这里的requestBody应该和上面提到的Type1
一样
API feedType == Type2 的 URI:/uploadFeed/feedType/{Type2}。这里的requestBody应该和上面提到的Type2
一样
Solution Proposal-2:有一个端点同时存在两个模型。
对于作为 TYPE1 的 feedType,预期的 requestBody 应为
{
"feedType":"TYPE1",
"type1Model": {
"a": "somevalue"
"b" : "somevalue",
"c" : "somevalue",
},
"type2Model" : null
}
对于作为 TYPE2 的 feedType,预期的 requestBody 应为
{
"feedType":"TYPE1",
"type1Model" : null
"type2Model": {
"x": "somevalue"
"y" : "somevalue",
"z" : "somevalue",
},
}
还有没有其他可能的方法。请提出可能的最佳解决方案(不一定是这两个)。
虽然为每种类型使用自己的端点或者甚至引入定义支持字段的特殊媒体类型可能很诱人,但这可能会以某种方式导致客户端期望资源具有特定类型的情况,which they don't,因此与模式紧密耦合,如果稍后更改可能会导致麻烦,这在 REST 架构中随时可能发生。
由于 REST 实际上只是可浏览 Web 中使用的概念的概括,因此可以在 Web 上使用的相同技术应该在 REST 架构中采用。
因此,您的主要目标之一应该始终是服务器教客户端如何实现目标。 Web 通过 HTML forms that not only teach a client on the supported and/or expected input data but also on the target URI to send the request to, the HTTP operation to use as well as the media-type to send a representation for, which is often implicitly given by application/x-www-form-urlencoded
. For JSON based representation formats hal-forms or ion 的帮助完成此操作可能有助于实现此目的。
交换的表示格式应尽可能通用,但同样也要尽可能具有表现力。如果你看一下 HTML 即你可以在其中表达任何东西,毕竟它只是一个网页。描述您喜欢的汽车型号或运动队的网页的处理方式与任何其他网页相同,并且不会提示您的 Web 客户端(浏览器)页面 returns 表示汽车或运动队的特定数据人类能够识别数据并将此类对象与其相关联。
由于应用程序(或一般的计算机)很难自行推断出此类关系,因此应进一步提示客户端资源的用途,尤其是关于客户端获取的当前状态。在这里,所谓的 link 关系名称的使用是必不可少的。它们或多或少代表了 URI 附带的注解,允许 URI 随着时间的推移而改变而不会失去表现力。您可能已经熟悉 link 关系名称,例如 first
、prev
、self
、next
和 last
在分页的上下文中是解释性的,尽管这样的 link 关系可以用来提示客户接下来将通过 prefecth
请求一些相关资源(想想一个新闻页面,其中给出了一个简短的预告片在一篇文章上,服务器可能会提示客户端接下来可能会请求完整的文章,因此客户端已经可以在后面下载文章,将其放入缓存中并允许客户端更快地检索该内容) .然而,这样的 link 关系不应该凭空出现,因为可以从字面上把任何东西放在那里,客户应该知道他们表达的是什么。因此 link 关系名称应为 standardized to gain widespread adoption or at least follow common practices as defined in Web linking,这会将 link 关系名称分配给专用名称空间以防止名称冲突。
最后,作为服务器端开发人员,您的主要目标是实现某种状态机,或者如 Jim Webber (2011) 所说的那样 Domain Application Protocol
,客户端只需执行,例如在亚马逊或您喜欢的网上商店订购,客户基本上只是按照服务器给出的选择来完成购买某些商品的任务。
我有一个 REST API uploadFeed 上传基于 feedType 的用户提要(字符串值作为请求正文的一部分输入)。不同的 feedtype 在请求正文中提供了不同的 pojo 模型。
例如,如果 feedType 是 "TYPE1",那么 API 的请求正文应该如下所示:
{
"feedType":"TYPE1",
"inputModel": {
"a": "somevalue"
"b" : "somevalue",
"c" : "somevalue",
}
}
如果 feedType 是 "TYPE2",那么 API 的请求正文应该如下所示:
{
"feedType":"TYPE2",
"inputModel": {
"x": "somevalue"
"y" : "somevalue",
"z" : "somevalue",
}
}
什么是最好的API uploadFeed 的设计API。我正在考虑两种可能的解决方案:
解决方案建议 1:有两个不同的 API 端点。
API feedType == Type1 的 URI:/uploadFeed/feedType/{Type1}。这里的requestBody应该和上面提到的Type1
一样
API feedType == Type2 的 URI:/uploadFeed/feedType/{Type2}。这里的requestBody应该和上面提到的Type2
一样
Solution Proposal-2:有一个端点同时存在两个模型。 对于作为 TYPE1 的 feedType,预期的 requestBody 应为
{
"feedType":"TYPE1",
"type1Model": {
"a": "somevalue"
"b" : "somevalue",
"c" : "somevalue",
},
"type2Model" : null
}
对于作为 TYPE2 的 feedType,预期的 requestBody 应为
{
"feedType":"TYPE1",
"type1Model" : null
"type2Model": {
"x": "somevalue"
"y" : "somevalue",
"z" : "somevalue",
},
}
还有没有其他可能的方法。请提出可能的最佳解决方案(不一定是这两个)。
虽然为每种类型使用自己的端点或者甚至引入定义支持字段的特殊媒体类型可能很诱人,但这可能会以某种方式导致客户端期望资源具有特定类型的情况,which they don't,因此与模式紧密耦合,如果稍后更改可能会导致麻烦,这在 REST 架构中随时可能发生。
由于 REST 实际上只是可浏览 Web 中使用的概念的概括,因此可以在 Web 上使用的相同技术应该在 REST 架构中采用。
因此,您的主要目标之一应该始终是服务器教客户端如何实现目标。 Web 通过 HTML forms that not only teach a client on the supported and/or expected input data but also on the target URI to send the request to, the HTTP operation to use as well as the media-type to send a representation for, which is often implicitly given by application/x-www-form-urlencoded
. For JSON based representation formats hal-forms or ion 的帮助完成此操作可能有助于实现此目的。
交换的表示格式应尽可能通用,但同样也要尽可能具有表现力。如果你看一下 HTML 即你可以在其中表达任何东西,毕竟它只是一个网页。描述您喜欢的汽车型号或运动队的网页的处理方式与任何其他网页相同,并且不会提示您的 Web 客户端(浏览器)页面 returns 表示汽车或运动队的特定数据人类能够识别数据并将此类对象与其相关联。
由于应用程序(或一般的计算机)很难自行推断出此类关系,因此应进一步提示客户端资源的用途,尤其是关于客户端获取的当前状态。在这里,所谓的 link 关系名称的使用是必不可少的。它们或多或少代表了 URI 附带的注解,允许 URI 随着时间的推移而改变而不会失去表现力。您可能已经熟悉 link 关系名称,例如 first
、prev
、self
、next
和 last
在分页的上下文中是解释性的,尽管这样的 link 关系可以用来提示客户接下来将通过 prefecth
请求一些相关资源(想想一个新闻页面,其中给出了一个简短的预告片在一篇文章上,服务器可能会提示客户端接下来可能会请求完整的文章,因此客户端已经可以在后面下载文章,将其放入缓存中并允许客户端更快地检索该内容) .然而,这样的 link 关系不应该凭空出现,因为可以从字面上把任何东西放在那里,客户应该知道他们表达的是什么。因此 link 关系名称应为 standardized to gain widespread adoption or at least follow common practices as defined in Web linking,这会将 link 关系名称分配给专用名称空间以防止名称冲突。
最后,作为服务器端开发人员,您的主要目标是实现某种状态机,或者如 Jim Webber (2011) 所说的那样 Domain Application Protocol
,客户端只需执行,例如在亚马逊或您喜欢的网上商店订购,客户基本上只是按照服务器给出的选择来完成购买某些商品的任务。