javajsonrestextendingmultiple-input

Extend Single ID REST endpoint to support multiple IDs


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


Solution

  • I find the path product/{id}/update questionable, because you could achieve similar behavior by mapping @Put-request to product/{id} itself. The READ, WRITE differentiation is already explicit by the Request-mapping. Also, whether or not using verbs in restful urls is a topic for itself.

    Assuming you could use plural endpoints, this could look like /products/{id}.

    Because you want to batch/bulk update products, you could map @Put-requests to /products now, with a list of updated Products in the RequestBody. Keep in mind, that this somewhat complicates the Response, as you may have to return Http-207 for answering the correct status of the update for each element in the list.

    I want 1 logical endpoint for update

    You can have a logical service method for this, but not endpoints really. You already mentioned the problem of /{id} in your path for bulk updates. If you really, really need to, I would remove the @Put-mapping from /products/{id} and redirect to /products where the update content would be a single element list, or a little more sophisticated, distinguished by a mediaType (what again means two endpints, but a single url).

    Edit: I just happen to understand the VO-issue. You are not updating Products, but parts of it (the name RequestVO was misleading me). This smells like a @Patch-mapping to me, where parts of a Product get updated. So I still would use /products but with a @Patch-mapping.

    When a client needs to replace an existing Resource entirely, they can use PUT. When they’re doing a partial update, they can use HTTP PATCH.

    This brings up another issue, use @Post only if the id is unknown (usually before something is CREATED and gets an id assigned, for UPDATES use @Put and reuse the assigned id) Using post is technically doable, but because of idempotece not advisable.