Ankur Pathak opened SPR-17031 and commented

Their is no support for View Controller In Spring Web Flux. Why not have addViewControllers(ViewControllerRegistry registry) method in WebFluxConfigurer similar to WebMvcConfigurer?

Their is no support for Welcome page like index.html also.


Affects: 5.0 GA

Reference URL: https://github.com/spring-projects/spring-boot/issues/9785

Comment From: spring-projects-issues

Rossen Stoyanchev commented

Indeed no reason not to. I'm assigning to 5.x backlog only because it's a bit late for the 5.1 backlog.

Comment From: spring-projects-issues

Rossen Stoyanchev commented

For the welcome page, we can make sure a default page can be mapped with a view controller but the actual welcome page would have to come from Boot.

Comment From: spring-projects-issues

Ankur Pathak commented

Can't we have Servlets semantics for welcome page. We would register default.html, index.html, index.htm as default views in view registry and render them in order. In case we use explicit view mapped to root path, it will overwrite them.

Comment From: bclozel

Taking a step back, the main goals behind this are in my opinion:

  • feature parity with Spring MVC
  • providing a way to register views without writing actual controller handlers
  • allowing Spring Boot to register the "welcome page" (not related to Servlet welcome pages!)

In Spring MVC, this is achieved thanks to the Controller and AbstractController hierarchy: we've got specific implementations that map paths to ModelAndView values pointing to views. We're also supporting more features, like customizing the HTTP response status.

In Spring WebFlux, the infrastructure is different and we can't implement it the same way. We could however use the RouterFunction to programmatically register such mappings and reuse the existing infrastructure (view resolvers, handler mapping, etc).

The implementation (minus the registry/registration classes) would look like this:

/**
 * Return the {@code RouterFunction} that contains the registered view
 * controller mappings, or {@code null} for no registrations.
 * @since 5.3.0
 */
@Nullable
protected RouterFunction<ServerResponse> buildRouterFunction() {

  return RouterFunctions.route()
      .GET("/", (req) -> ServerResponse.ok().render("home", Collections.emptyMap()))
      //...
      .build();
}

The implementation itself is really short and could provide more flexibility about ordering, response headers, or even path matching - like mapping /pages/{name} to the view name. In my opinion, path matching and ordering are powerful options for JavaScript client applications or applications with many static pages.

I've had a look at other web frameworks, like Symfony, Rails and others. It looks like the approach taken by Laravel is quite similar to using RouterFunction directly.

With that in mind, I've got questions for @rstoyanchev and @poutsma :

  1. Should we target feature parity with MVC in this case?
  2. Should we recommend instead RouterFunction directly?
  3. Is this approach (contributing a RouterFunction bean to the context) problematic in any way (ordering, filtering of RouterFunction, etc)? In MVC, we were contributing a HandlerMapping with a customizable order defaulting to 1.

Comment From: bclozel

After discussing the previous comment with team members, it seems that the main driver for this feature is the welcome page support in Spring Boot.

There are many ways to achieve the equivalent of ViewController in WebFlux, including:

  • a new DSL that creates a component based on a new Controller interface (taking a WebExchange and returning Object)
  • a registry that creates a RouterFunction directly

Because there is a way to directly implement the welcome page use case in Spring Boot, we'll close this issue for now until we get new requirements and use cases from the community.