Статьи
Утилиты Telegram YouTube Отзывы

Обновление записи через PUT-запрос в Spring Boot

Исходники

28 декабря 2023

Тэги: Java, json, rest, Spring Boot, SQL, руководство.

Содержание

  1. Репозиторий
  2. Сервисный слой
  3. Контроллер

В предыдущей статье Добавление записи через POST-запрос в Spring Boot мы научились создавать новые записи в БД. Теперь попробуем создать полноценный rest-интерфейс для обновления ранее добавленных записей.

За основу возьмём наше приложение из указанной статьи. Оно состоит из трёх слоёв: репозиторий (работа с БД), бизнес-логика приложения (service) и сам rest-интерфейс (controller), который обрабатывает входящий json и генерирует исходящий.

Репозиторий

Начнём с доработки репозитория (интерфейс ProfileRepository).

void updateProfile(String firstName, String secondName, int age, int id);

Для обновления нам потребуется указать id записи, а также остальные значимые поля.

В реализацию интерфейса dao (ProfileRepositoryImpl) добавим sql-запрос в виде константы, которую принято размещать в начале класса:

private static final String SQL_UPDATE_PROFILE =
        "update profile set first_name = :firstName, last_name = :lastName, age = :age where id = :id";

Имена параметров, которые мы будем подставлять в sql-запрос, начинаются с двоеточия.

Вот реализация обновления записи в БД:

@Override
public void updateProfile(String firstName, String lastName, int age, int id) {
    var params = new MapSqlParameterSource();
    params.addValue("firstName", firstName);
    params.addValue("lastName", lastName);
    params.addValue("age", age);
    params.addValue("id", id);
    jdbcTemplate.update(SQL_UPDATE_PROFILE, params);
}

Всё предельно просто: сначала собираем параметры, затем передаём их вместе с запросом в метод jdbcTemplate.update(), который вопреки своему названию отвечает вообще за любые изменения данных (и insert, и update, и delete). Обратите внимание, что jdbcTemplate у нас имеет тип NamedParameterJdbcTemplate – именно он позволяет использовать именованные параметры. Иначе пришлось бы писать знаки вопроса.

Сервисный слой

Перейдём к сервисному слою. Интерфейс ProfileService не отличается оригинальностью:

void updateProfile(String firstName, String secondName, int age, int id);

Его реализация в ProfileServiceImpl:

@Override
public void updateProfile(String firstName, String secondName, int age, int id) {
    var profile = profileRepository.getProfileById(id)
            .orElseThrow(() -> new ProfileNotFoundException(id));
    profileRepository.updateProfile(firstName, secondName, age, profile.id());
}

Здесь операцию нужно выполнить над уже существующей записью, поэтому перед вызовом надо проверить её наличие в БД. Если по каким-то причинам её там не нашлось – сразу кидаем исключение, которое будет преобразовано в соответствующий json благодаря ErrorController, который мы рассматривали в предыдущей статье.

Контроллер

Согласно архитектуре restful-сервисов, чтение данных мы делаем при помощи GET-запросов, а изменение – при помощи PUT. Также хотелось бы отметить, что у GET-запроса не может быть тела запроса (body), все его параметры перечисляются в строке запроса. А PUT-запрос может иметь тело, в которое мы будем помещать целевой json.

Перейдём к нашему контроллеру ProfileController и добавим в него метод обновления профиля.

@PutMapping(value = "/{personId:\\d+}")
@ResponseStatus(HttpStatus.NO_CONTENT)
public void updateProfile(
        @Valid @RequestBody ProfileRequest request,
        @PathVariable int personId
) {
    profileService.updateProfile(
            request.firstName(),
            request.lastName(),
            request.age(),
            personId
    );
}

В качестве аргумента метод принимает модель запроса ProfileRequest, который мы рассматривали в предыдущей статье.

Аннотация @PutMapping говорит, что это – обработчик PUT-запроса, причём в адресной строке также требуется указать personId (после двоеточия указана регулярка, т.е. мы ожидаем любое количество цифр). Значение этого параметра будет помещено в соответствующую переменную благодаря @PathVariable. В ответ метод будет возвращать http-статус 204 – «No Content».

Теперь мы готовы к тому, чтобы выполнить rest-запрос на обновление новой записи в БД. Запускаем приложение и отравляем указанный PUT-запрос по адресу http://127.0.0.1:8080/profiles/1, где 1 – это номер существующей записи. В http-заголовках обязательно указываем Content-Type: application/json.

{
  "firstName": "Петр",
  "lastName": "Сидоров",
  "age": 14
}

В ответ в случае успеха получаем http-статус 204. А если укажем id записи, которой нет в БД, то получим следующий ответ:

{
  "message": "Profile with id = 123 not found"
}

Таким образом, Spring Boot позволяет буквально за 5 минут создать полноценный обработчик PUT-запроса с валидацией входящих параметров.

В следующей статье Удаление записи через DELETE-запрос в Spring Boot мы научимся удалять существующие записи из БД.



Комментарии

Добавить комментарий

×

devmark.ru