Расширение конечной точки REST с одним идентификатором для поддержки нескольких идентификаторов

У меня есть один ID REST API, который мне нужно расширить для поддержки нескольких (до 10 Кб) идентификаторов. В основном, для запуска обновления всех соответствующих идентификаторов вместо отправки запроса 10K в сети.

Текущая конечная точка:

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

Один из предложенных вариантов - значения, разделенные запятыми, как stackexchange-ответы-идентификаторы

Использование / answers / {ids} GET

{ids} может содержать до 100 идентификаторов, разделенных точкой с запятой. Чтобы найти идентификаторы программным способом, найдите answer_id для объектов ответа.

Это касается похожих ответов

http://our.api.com/Product/<id1>,<id2>: как предположил Джеймс, это может быть вариант, так как то, что следует после тега Product, является параметром

Но это кажется мне неловким и RequestVo будет одинаковым для всех идентификаторов (что в настоящее время хорошо, но позже добавить такую ​​поддержку будет сложнее)

Кажется, мне нужно изменить из переменной Path, чтобы добавить его в RequestVO

Это означает, что Id будет ключом JSON, например,

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

Это правильный подход или я что-то упустил?

Заранее благодарю за любые комментарии \ ответы

Текущий запрос В.О.

@Data
@AllArgsConstructor
@NoArgsConstructor
public class RequestVO {

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

Меня беспокоит также, если я хочу (одно из требований) обновить с тем же запросом (как name=doA, toggle=true) для идентификаторов 10Ks, мне придется дублировать VO запроса вместо того, чтобы отправлять ID отдельно

3 ответа

Решение

Я нахожу путь product/{id}/update сомнительно, потому что вы могли бы достичь аналогичного поведения путем сопоставления @Put-request в product/{id} сам. Дифференциация READ, WRITE уже явно указана в отображении запроса. Кроме того, является ли использование глаголов в успокоительных URL-адресах темой для себя.

Предполагая, что вы можете использовать множественные конечные точки, это может выглядеть так /products/{id},

Поскольку вы хотите выполнять пакетное / массовое обновление продуктов, вы можете отобразить @Put-requests в /products Теперь со списком обновленных продуктов в RequestBody. Имейте в виду, что это несколько усложняет ответ, так как вам, возможно, придется вернуться Http-207 для ответа на правильный статус обновления для каждого элемента в списке.

Я хочу 1 логическую конечную точку для обновления

Для этого у вас может быть логический метод обслуживания, но на самом деле нет конечных точек. Вы уже упоминали проблему /{id} на вашем пути для массовых обновлений. Если вам действительно очень нужно, я бы удалил @Putотображение из /products/{id} и перенаправить на /products где содержимое обновления будет представлять собой один список элементов или немного более сложный, различаемый mediaType (что опять же означает две конечные точки, но один URL).

Редактировать: я просто случайно понял вопрос VO. Вы обновляете не продукты, а их части (название RequestVO вводило меня в заблуждение). Это пахнет @Patch-mapping мне, где части продукта обновляются. Так что я бы еще использовал /products но с @Patch-mapping,

Когда клиенту необходимо полностью заменить существующий ресурс, он может использовать PUT. Когда они делают частичное обновление, они могут использовать HTTP PATCH.

Это поднимает еще одну проблему, используйте @Post только если идентификатор неизвестен (обычно перед тем, как что-то СОЗДАНО и получает назначенный идентификатор, для использования ОБНОВЛЕНИЙ @Put и повторно использовать назначенный идентификатор) Использование сообщения технически выполнимо, но из-за идемпотеза не рекомендуется.

Лучший способ сохранить id в вашей RequestVO DTO, а не в URL, как вы уже предлагали, потому что даже 100 идентификаторов в URL могут сделать ваш URL очень большим, а вы говорите о 10K идентификаторах.

И снова в будущем, битовая длина одного id может увеличиться или позже вам может понадобиться обновить 50К или даже 100К объектов.

В зависимости от максимальной длины URL-адреса нет общей спецификации длины URL-адреса, но очень длинные URL-адреса обычно являются ошибкой, и URL-адреса длиной более 2000 символов не будут работать в самых популярных веб-браузерах.

Поэтому я думаю, что ваш второй подход лучше всего подходит для будущих целей.

Вы также можете использовать PUT запрос, потому что это имеет больше смысла для запроса на обновление. Таким образом, ваш код станет таким:

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

Почему бы просто не передать список ваших идентификаторов в теле запроса в виде массива JSON? код будет:

@POST
@Path("/update/ids")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ResponseVO updateBlockReason(@RequestBody List<Integer> ids, List<RequestVo> requestVo) {
...
}
Другие вопросы по тегам