5

I have a single ID REST API that I need to extend to support multiple (up to 10Ks) IDs. Basically to run update on all relevant IDs instead of sending 10Ks request in network.

Current endpoint:

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

One option suggested is comma-delimited values as stackexchange's answers-by-ids

Usage of /answers/{ids} GET

{ids} can contain up to 100 semicolon delimited ids. To find ids programmatically look for answer_id on answer objects.

This is the case on similar answers

http://our.api.com/Product/<id1>,<id2> :as James suggested can be an option since what comes after the Product tag is a parameter

But it seems awkward to me and RequestVo will be same for all IDs (which is currently is fine, but later to add such support will be harder)

It seems I need to change from Path variable to add it inside RequestVO

Which means the Id will be a JSON key, e.g.

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

Is this the correct approach or am I missing something?

Thank you in advance for any comments\answers

Current request VO

@Data
@AllArgsConstructor
@NoArgsConstructor
public class RequestVO {

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

My concern is also if I want (one of the requirement) to update with same request (as name=doA, toggle=true) for 10Ks Ids I'll have to duplicate request VO instead of sending ID separately

4

3 回答 3

4

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

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

根据 URL 的最大长度,没有关于 URL 长度的通用规范,但极长的 URL 通常是错误的,超过 2,000 个字符的 URL 在最流行的 Web 浏览器中无法正常工作

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

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

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

于 2019-07-07T09:19:06.740 回答
1

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

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

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

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

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

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

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

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

于 2019-07-07T08:42:19.577 回答
0

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

@POST
@Path("/update/ids")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ResponseVO updateBlockReason(@RequestBody List<Integer> ids, List<RequestVo> requestVo) {
...
}
于 2019-07-07T12:22:06.870 回答