As detailed previously, we have two approaches, namely functional-based and annotation-based, for implementing a WebFlux application. Annotation-based is similar to Spring MVC, and because of this, we will be using functional-based approach in our sample application:
@Component
public class MovieHandler {
private final MovieRepository movieRepository;
public MovieHandler(MovieRepository movieRepository) {
this.movieRepository = movieRepository;
}
public Mono<ServerResponse> listMovies(ServerRequest request) {
// fetch all Movies from repository
Flux<Movie> movies = movieRepository.listMovies();
// build response
return
ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(movies, Movie.class);
}
//...Other methods
}
The class is quite straightforward and uses a repository class for data structure query and manipulation. Each method accomplishes the functionality, and finally returns Mono<ServerResponse>. Another important aspect of WebFlux in functional-based programming is the routing configuration class, as follows:
@Configuration
public class RouterConfig {
@Bean
public RouterFunction<ServerResponse> routerFunction1(MovieHandler
movieHandler) {
return
route(GET("/").and(accept(MediaType.APPLICATION_JSON)),
movieHandler::listMovies)
.andRoute(GET("/api/movie").and(accept(MediaType.APPLICATION_JSON)),
movieHandler::listMovies)
.andRoute(GET("/api/movie/{id}").and(accept(MediaType.APPLICATION_JSON)),
movieHandler::getMovieById)
.andRoute(POST("/api/movie").and(accept(MediaType.APPLICATION_JSON)),
movieHandler::saveMovie)
.andRoute(PUT("/api/movie/{id}").and(accept(MediaType.APPLICATION_JSON)),
movieHandler::putMovie)
.andRoute(DELETE("/api/movie/{id}")
.and(accept(MediaType.APPLICATION_JSON)), movieHandler::deleteMovie);
}
}
This is the class that looks at the request and routes it to the appropriate handler method. In your application, you can have any number of router configuration files.