Уровень контроллеров проверки ограничений по сравнению с уровнем сервиса - PullRequest
0 голосов
/ 31 августа 2018

Я пытаюсь освоить весну и добиться этого, я создаю REST-приложение с нуля. Я запутался, где я должен проверить ограничения в моем приложении: уровень контроллера или уровень обслуживания. Например, в методе создания пользователя я хочу проверить, есть ли другой пользователь с таким же адресом электронной почты, поскольку адрес электронной почты уникален в моей базе данных. Я также хочу проверить, совпадает ли пароль (поля «пароль» и «подтвердить пароль») и т. Д.

В настоящее время в моей реализации все это проверяется на уровне контроллера, поэтому я могу вернуть ResponseEntity для каждого подхода.

    @PostMapping("/signUp")
    public ResponseEntity<Object> createUser(@RequestBody RegisterUserDto user) {

        if (userService.getUserByEmail(user.getEmailAddress()) != null) {

            return ResponseEntity.badRequest().body("email already exists");
        }

        if (!user.getPassword().equals(user.getConfirmPassword())) {

            return ResponseEntity.badRequest().body("passwords are not the same");
        }

        User savedUser = null;

        try {

            savedUser = userService.createUser(userDtoConversions.convertToEntityRegister(user));

        } catch (ParseException e) {

            e.printStackTrace();
        }

        URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}")
                .buildAndExpand(savedUser.getId()).toUri();

        return ResponseEntity.created(location).build();
    }

Создание метода пользователя в слое Service:

    @Override
    @Transactional
    public User createUser(User newUser) {

        newUser.setDateCreated(new Date());

        return userRepository.save(newUser);
    }

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

1 Ответ

0 голосов
/ 31 августа 2018

На мой взгляд, лучшее место для обработки исключений - уровень обслуживания. Для меня метод контроллера REST должен, в лучшем случае, обрабатывать запрос и передавать его в сервисный метод.

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

Имея это в виду, ничто не мешает вам создавать какие-либо исключения в слое обслуживания и переводить их в правильные ответы. Spring имеет очень аккуратный и мощный механизм, который делает именно то, что называется обработчиком исключений.

Так что в вашем случае для действия по проверке пароля вы можете сделать что-то вроде:

if (!user.getPassword().equals(user.getConfirmPassword())) {
    throw new PasswordMismatchException("Passwords are not the same for user:: " + user.getName());
}

Где PasswordMismatchException - это исключение RuntimeException. Имея что-то подобное, вы можете затем установить ExceptionHandler и соответствующий метод, чтобы перехватить это и преобразовать в ответ. Простым примером будет:

@RestControllerAdvice
public class ApplicationExceptionHandler {

   @ExceptionHandler(PasswordMismatchException.class)
   public ResponseEntity<String> handleBadPasswords(PasswordMismatchException e) {
       return ResponseEntity.badRequest().body(e.getMessage());
   }

}

Подробнее об этом вы можете прочитать в документации Spring:

Spring ExceptionHandler

Обработка исключений весной

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...