Как правильно структурировать конечные точки REST для PUT и POST - PullRequest
0 голосов
/ 22 июня 2019

У меня есть служба REST для управления пользователями.

HTTP GET ("/ users") - получить всех пользователей
HTTP GET ("/ users / {id}") - получить данные для конкретного пользователя

При изменении чего-либо о пользователе я не уверен, как структурировать пути для PUT / PATCH.

Вариант 1:
HTTP PUT ("/ users") и передача пользовательских данных (идентификатор, имя, фамилия) в теле запроса
HTTP PATCH ("/ users") и передача идентификатора пользователя и PASSWORD в теле запроса

Вариант 2:
HTTP PUT ("/ users / {id}") и передача пользовательских данных (id, имя, фамилия) в теле запроса
HTTP PATCH ("/ users / {id}") и передача ИД пользователя и ПАРОЛЯ в теле запроса

Вариант 3:
HTTP PUT ("/ users / {id}") и передача пользовательских данных (id, имя, фамилия) в теле запроса
HTTP PATCH ("/ users / {id} / password") и передача ID пользователя и ПАРОЛЯ в теле запроса

@ RequestMapping (value = "/ users") открытый интерфейс UserController {

@GetMapping(value = "/{id}", produces = "application/json")
User getUser(@PathVariable long id);

@PutMapping(value = "", consumes = "application/json")
void addNewUser(@RequestBody User ser);

@PatchMapping(value = "/{id}/password", consumes = "application/json")
void changeUserPassword(@RequestBody UserPasswordChange passwordChangeModel, @PathVariable String id);

Я не уверен, какой из этих подходов является лучшим. Я могу получать все данные из тела запроса каждый раз, но я не уверен, какой путь должен быть наилучшим для создания. Использование «/ users / {id}» для изменения сведений о пользователе имеет смысл, потому что я меняю для конкретного пользователя, но, поскольку я могу прочитать идентификатор из тела запроса, переменная пути здесь избыточна.

Это та же путаница при смене пароля. Поскольку у меня есть только одна конечная точка Patch в разделе "/ users", мне все равно следует использовать "/ users / {id} / password" или, возможно, мне следует удалить часть "/ password"?

1 Ответ

1 голос
/ 23 июня 2019

Когда я что-то изменяю в пользователе, я не уверен, как структурировать пути для PUT / PATCH.

И PUT, и PATCH являются запросами на редактирование документа. «Пожалуйста, сделайте ваше представление об этом ресурсе похожим на мое».

В идеализированной форме у меня был бы какой-то редактор документов с поддержкой HTTP. Я GET представлю вам ресурс, внесу изменения в мою локальную копию, а затем отправлю вам представление моей локальной копии.

Получение полезной работы является побочным эффектом передачи этих документов. См. Доклад Джима Уэббера .

Варианты 1, я думаю, мы можем просто отказаться от первых принципов. Если ресурс, обозначенный /users, представляет собой совокупность пользователей, то попытка заменить его представление на представление одного пользователя не является шагом в полезном направлении. Семантически, если вы хотите отредактировать или вставить пользователя, взаимодействуя с ресурсом /users, вы сделаете это либо (а) путем внесения изменений в представление коллекции и отправки всего представления обратно (PUT), либо отправив описание diff обратно на сервер (PATCH).

Вариант 2, имеет более тонкую проблему - если пароль является частью представления ресурса /users/id, то пароль также должен быть частью тела запроса PUT. PUT и PATCH - это разные способы передачи нашего локального представления ресурса обратно на сервер; мы не должны думать о них как о другой информации о ресурсе.

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

То есть вы предлагаете, чтобы вариант 3 имел смысл?

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

...