Piszę swoją aplikację korzystając z biblioteki Vavr i flow programu jest sterowany za pomocą Either.
Mam jednak mieszane uczucia czy w ogóle dobrze do tego podchodzę...
Mam metodę która tworzy użytkownika, pod spodem której dzieje się całkiem sporo
-sprawdzana jest poprawność danych
-walidacja czy taki użytkownik już nie istnieje
-generowanie tokenu aktywacji konta
-zapisanie użytkownika na bazie
-wysyła maila z linkiem do aktywacji
I większość z tych metod, które są wołane, zwraca Either<Error, Success>
Po kolei wygląda to tak, sama metoda createUser oraz metody pomocnicze
Either<DomainError, SuccessMessage> createUser(RegisterUserDto registerUserDto) {
var validationError = validate(registerUserDto);
if(validationError.isPresent()) return Either.left(validationError.get());
final var token = generateToken(registerUserDto.getUsername());
final var user = User.createUser(registerUserDto);
final var savedUser = user.map(this::saveUser);
return savedUser.isRight() && token.isRight() ?
emailFacade.sendActivationEmail(registerUserDto.getUsername(), registerUserDto.getEmail(), token.get())
: Either.left(savedUser.getLeft());
}
private Optional<DomainError> validate(RegisterUserDto userDto) {
if(userRepository.findByUsername(userDto.getUsername()).isPresent()) return Optional.of(UserError.USERNAME_ALREADY_EXISTS);
if(userRepository.findByEmail(userDto.getEmail()).isPresent()) return Optional.of(UserError.EMAIL_ALREADY_EXISTS);
return Optional.empty();
}
private Either<DomainError, String> generateToken(String username) {
return Try.of(() -> tokenRepository.generateToken(username))
.onFailure(e -> log.severe(e.getMessage()))
.toEither(UserError.PERSISTENCE_FAILED);
}
private Either<DomainError, User> saveUser(User user) {
return Try.of(() -> save(user))
.onFailure(e -> log.severe(e.getMessage()))
.toEither(UserError.PERSISTENCE_FAILED);
}
private User save(User user) {
userRepository.saveUser(objectMapper.userToDto(user));
return user;
}
Encja usera
static Either<DomainError, User> createUser(RegisterUserDto dto) {
return validEmail(dto.getEmail()) ?
Either.right(User.builder()
.username(dto.getUsername())
.password(dto.getPassword())
.email(dto.getEmail())
.active(false)
.roles(Set.of("USER"))
.build()) :
Either.left(UserError.INVALID_EMAIL);
}
No i inna domena która jest tu wołana
public Either<DomainError, SuccessMessage> sendActivationEmail(String username, String receiver, String token) {
return emailService.sendEmail(username, receiver, token);
}
No i zastanawiam się czy to w ogóle ma ręce i nogi, ciężko o jakieś bardziej skomplikowane przykłady w Internecie więc fajnie jakby ktoś kto korzysta z tego na co dzień spojrzał krytycznym okiem.