I need help with Vavr in Java. I have a business process to update a book entity and I want to make validations before every update.
Steps:
BookUpdateDto
.BookById
; return Book if exists or return Either with BOOK_NOT_FOUND
.BookUpdateDto
to BookCreateDto
and validate.Validation<Seq<String>, BookCreateDto>
and that's my problem.public Either<BookError, BookCreateDto> updateBookById(final Long bookId, final BookUpdateDto toUpdate) {
return findBookById(bookId)
.toEither(BOOK_NOT_FOUND)
.map(Book::response)
.map(bookValidation::validate)
.map(book -> book.mapToUpdate(toUpdate))
.map(book -> book.update(toUpdate))
.map(book -> bookRepository.save(book).response());
}
I do not know how to map my errors from validation and domain error that BOOK_NOT_FOUND
in empty space in code. Or maybe my architecture to solve my problem is wrong.
It looks like Validation.toEither
combined with a flatMap
could do the trick.
The toEither changes the Validation
into an Either<List<String>, BookCreateDto>
and the mapLeft
on that either changes the left side of the either from List<String>
to a BookError
.
public Either<BookError, BookCreateDto> updateBookById(final Long bookId, final BookUpdateDto toUpdate) {
return findBookById(bookId)
.toEither(BOOK_NOT_FOUND)
.map(Book::response)
.map(bookValidation::validate)
// This should perform the desired conversion
.flatMap(validation -> validation.toEither().mapLeft(this::validationErrorsToBookError))
.map(book -> book.mapToUpdate(toUpdate))
.map(book -> book.update(toUpdate))
.map(book -> bookRepository.save(book).response());
}
The validationErrorsToBookError
would be a function that is responsible for turning a list of validations into a BookError
. Probably something along these lines:
BookError validationErrorsToBookError(Seq<String> validationErrors) {
// Use logic that would fit your specific needs for BookErrors
return new BookError(validationErrors.mkString(";"));
}