【问题标题】:Extend Single ID REST endpoint to support multiple IDs扩展 Single ID REST 端点以支持多个 ID
【发布时间】:2019-11-12 03:26:00
【问题描述】:

我有一个 ID REST API,我需要扩展它以支持多个(最多 10Ks)ID。基本上是在所有相关 ID 上运行更新,而不是在网络中发送 10Ks 请求。

当前端点:

@POST
@Path("{id}/update")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ResponseVO updateBlockReason(@PathParam("id") int id, List<RequestVo> requestVo) {

一个选项suggestedstackexchange's answers-by-ids 的逗号分隔值

/answers/{ids} GET 的使用

{ids} 最多可以包含 100 个分号分隔的 id。要以编程方式查找 id,请在 answer 对象上查找 answer_id。

similar answers就是这种情况

http://our.api.com/Product/&lt;id1&gt;,&lt;id2&gt; :正如詹姆斯建议的那样,可以选择,因为产品标签后面的内容是一个参数

但这对我来说似乎很尴尬,RequestVo 对于所有 ID 都是相同的(目前很好,但以后添加这样的支持会更难)

看来我需要从 Path 变量中更改以将其添加到 RequestVO 中

这意味着 Id 将是 JSON 密钥,例如

[{
"id" : "1",
"name": "myAttribute"
"toggle": true
},
{
"id" : "2",
"name": "mySecondAttribute"
"toggle": false
}
]

这是正确的方法还是我遗漏了什么?

提前感谢您提供任何 cmets\answers

当前请求语音

@Data
@AllArgsConstructor
@NoArgsConstructor
public class RequestVO {

 private String name;
 private boolean toggle;
 // will add now private int id
 }

我还担心,如果我想(其中一项要求)使用相同的请求(如 name=doA,toggle=true)更新 10Ks Id,我将不得不复制请求 VO 而不是单独发送 ID

【问题讨论】:

  • 我会在请求正文中添加标识符列表,拥有大量请求参数有点尴尬。
  • @TA 所以我的方法是正确的
  • 我不太明白您的RequestVo 与您的标识符有什么关系,您能详细说明一下吗?如果你想为每个 id 更新这些对象,除了你的 List&lt;RequestVo&gt; requestVo 之外,我只会传递一个 List&lt;Integer&gt; ids 而不是合并这两个。
  • @TA 合并时不会引起问题吗?如果我会在 RequestVO 中获得 5 号 id 和 2 号?
  • 为什么不添加一个像updateBlockReasonBatch 这样没有{id} 路径变量的新端点,而只使用一个带有id列表的主体?

标签: java json rest extending multiple-input


【解决方案1】:

最好的方法是将 id 保留在您的 RequestVO DTO 本身中,而不是像您已经建议的那样保留在 URL 中,因为即使 URL 中的 100 个 id 也会使您的 URL 变得非常大,而您正在谈论 10K id。

同样,在未来,单个id 的位长可能会增加或稍后您可能需要更新 50k 甚至 100K 对象。

根据maximum length of a URL,没有关于 URL 长度的通用规范,但极长的 URL 通常是错误的,超过 2,000 个字符的 URL 在最流行的网络浏览器中无法使用

所以我认为你的第二种方法在这里最好,并且对未来的目的也有好处。

您可能还想使用PUT 请求,因为它对更新请求更有意义。所以你的代码会变成这样:

@PUT
@Path("/update")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ResponseVO updateBlockReason(List<RequestVo> requestVo) {

【讨论】:

  • 我担心的是,如果我想(其中一项要求)使用相同的请求(如 name=doA,toggle=true)更新 10Ks Id,我将不得不复制请求 VO 而不是发送分别标识
  • 我不明白你的担心,你能解释一下吗?如果不在评论中,则可能在问题本身中。
  • 我的 JSON 将有 id:1 name:doA, toggle:true, id:2,name:doA, toggle:true, id:3,name:doA, toggle:true, ...似乎重复的名称/切换,但也许没有其他方法
  • 如果多个 id 表示多个数据库对象或行,如果多个 Db 行可以具有相同的数据(相同的名称和切换)并且所有这些对象都需要更新。但如果这不是你的情况,那么你可以在你的 API 中使用一些逻辑来处理这个问题,或者在调用你的 API 时作为逻辑来处理。
【解决方案2】:

为什么不将请求正文中的 ID 列表作为 JSON 数组传递?代码是:

@POST
@Path("/update/ids")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ResponseVO updateBlockReason(@RequestBody List<Integer> ids, List<RequestVo> requestVo) {
...
}

【讨论】:

  • 当 id 的大小与 requestVo 不同时会发生什么?如何在它们之间正确映射?
  • 好吧,理想情况下,您只需将 id 作为 RequestVo 的属性之一包括在内,然后您就不需要映射。我只是指出了在请求正文而不是 URL 中传递长信息的明显解决方案
【解决方案3】:

我发现路径 product/{id}/update 有问题,因为您可以通过将 @Put-request 映射到 product/{id} 本身来实现类似的行为。 Request-mapping 已经明确了 READ、WRITE 的区别。 另外,是否在 restful url 中使用动词本身就是一个话题。

假设您可以使用多个端点,这可能看起来像 /products/{id}

因为您想批量/批量更新产品,您现在可以将@Put-requests 映射到/products,并在 RequestBody 中包含更新的产品列表。请记住,这会使响应变得有些复杂,因为您可能必须返回 Http-207 才能回答列表中每个元素的正确更新状态。

我想要 1 个逻辑端点进行更新

您可以为此使用逻辑服务方法,但实际上没有端点。 您已经在批量更新的路径中提到了/{id} 的问题。 如果你真的真的需要,我会从/products/{id} 中删除@Put-mapping 并重定向到/products,其中更新内容将是单个元素列表,或者更复杂一点,由 mediaType 区分(什么再次表示两个端点,是一个 url)。

编辑: 我只是碰巧理解了VO问题。您不是在更新产品,而是更新其中的一部分(RequestVO 这个名字误导了我)。 对我来说,这闻起来像 @Patch-mapping,其中部分产品会得到更新。 所以我仍然会使用/products,但使用@Patch-mapping

当客户端需要完全替换现有资源时,他们可以使用 PUT。当他们进行部分更新时,他们可以使用 HTTP PATCH。

这带来了另一个问题,只有在 id 未知时才使用@Post(通常在创建某些东西并获得分配的 id 之前,对于更新使用 @Put 并重用分配的 id) 使用 post 在技术上是可行的,但由于 idempotece 不建议使用。

【讨论】:

  • 感谢您的回答,总结一下我将删除Path并使用@PUT支持幂等并将id移动到VO。发送多达 10 万个 ID 是否安全,或者 API 是否应该限制它?
  • 我可能会支持 1k 或更小的块,这在很大程度上取决于您的情况。请记住,某些更新可能由于某种原因而失败,您必须/应该告诉客户更新结果如何。而不是 Put 看看 Patch,因为它看起来更适合 VO 不是产品被传达的情况。补丁也可以是幂等的,具体取决于您的实现。是的,productId 应该在 requestVO 中作为产品的键。
  • 我主要关心的是,如果我想(当前要求)做同样的操作,例如所有 ID 的 name=doA 和 toggle=true,似乎为每个 ID 复制数据
  • 你的意思是RequestBody中的操作参数重复?这取决于你。您可以设计一个 PatchVO,它需要一个 Id 列表和一个操作参数。而不是每个都有 id 和 param 的列表。我对您的领域没有足够的了解,但这可能会有所不同。至少可以做的是记录 PatchVO 及其含义,以免混淆客户。
猜你喜欢
  • 2017-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-10
  • 2020-12-31
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
相关资源
最近更新 更多