Using a service to encapsulate business logic

It is a good practice to encapsulate business logic inside Service methods so that controllers and repositories are loosely coupled. The following is a Service written to encapsulate the business logic for Movie:

@Service
class MovieService constructor(val movieRepository: MovieRepository) {

fun findAll() = this.movieRepository.findAll();

fun save(movie : Movie) : Mono<Movie> = this.movieRepository.save(movie);

fun findOne(id : Int) : Mono<Movie> = this.movieRepository.findById(id)
.switchIfEmpty(Mono.error(MovieNotFoundException.create(id)));

fun rate(id : Int, comment : String, rating : Int) : Mono<Movie> {
var movieMono: Mono<Movie> = this.findOne(id);
return
movieMono.switchIfEmpty(Mono.error
(MovieNotFoundException.create(id))).map({ movie ->
movie.ratings.add(MovieRating(comment, rating, Date()));
movie;
}).map({ movie ->
this.save(movie).subscribe();
movie;
});
}

}

in the preceding code, MovieService is annotated with the @Service stereotype annotation to mark it as a Spring Service. When a movie specified by an ID does not exist, MovieNotFoundException is thrown. The following is the implementation of this:

class MovieNotFoundException : Exception {

constructor(message : String) : super(message);

companion object {
fun create(id : Int) : MovieNotFoundException {
return MovieNotFoundException("Movie by id $id, not
found"
);
}
}

}

The MovieNotFoundException phrase extends the Exception class and has a companion object to create instances with an appropriate message. 

Likewise, the following UserService is used for User:

@Service
class UserService(val userRepository: UserRepository) {

fun getByUsername(username : String) : Flux<User> {
return userRepository.findByUsername(username);
}

fun save(user : User) : Mono<User> {
return userRepository.save(user);
}
}

This Service class has functions to save and get the user using their username. Also, there is a Spring Security Reactive-specific service that is implemented to load users by username using UserService and return as a Spring Security user to successfully authenticate users. The following MovieeReactiveUserDetailsService implements the ReactiveUserDetailsService.findByUsername() function:

@Service
class MovieeReactiveUserDetailsService(val userService : UserService) : ReactiveUserDetailsService {

override fun findByUsername(username: String?): Mono<UserDetails> {
if (username != null) {
return userService.getByUsername(username).toMono().map({
user -> User.withUsername(user.username).password
(user.password).roles(user.role).build();
});
}

return Mono.empty();
}
}

The preceding service makes use of UserService to get the user using their username and convert them into a Spring Security user, before returning Mono<UserDetails>.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.62.105