Расширение конечной точки REST с одним идентификатором для поддержки нескольких идентификаторов - PullRequest
4 голосов
/ 01 июля 2019

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

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

@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
}
]

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

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

Текущий запрос VO

@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 ]

4 голосов
/ 07 июля 2019

Лучший способ - сохранить 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) {

1 голос
/ 07 июля 2019

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

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

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

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

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

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

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

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

0 голосов
/ 07 июля 2019

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

@POST
@Path("/update/ids")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public ResponseVO updateBlockReason(@RequestBody List<Integer> ids, List<RequestVo> requestVo) {
...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...