Skip to content

Can't use RouterFunction and RestController together [SPR-15405] #19968

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Apr 2, 2017 · 5 comments
Closed
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement

Comments

@spring-projects-issues
Copy link
Collaborator

spring-projects-issues commented Apr 2, 2017

Jonathan Borenstein opened SPR-15405 and commented

If you have a routerfunction, no matter where you map it to, you can't have a RestController in your application.

You either choose one or the other. Why not both? Or is this by design?


Affects: 5.0 M5

Issue Links:

0 votes, 6 watchers

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented Apr 3, 2017

Brian Clozel commented

Hi Jonathan Borenstein,

The main goal with the WebFlux setup is to create a HttpHandler that handles incoming HTTP requests. You can create one using the application context, bringing together all the pieces given by the annotation flavor. Alternatively, you can create one using the provided RouterFunctions.

We could wire RouterFunctions and Controllers within a single HttpHandler, but in my opinion this would create quite a lot of limitations. One one side, Controller handlers are stored in a data structure and the matching process is done against those with the most specific routes first. The RouterFunctions are gathered in a single function which takes care of the routing by itself (so the order of declaration and the constructs you use to wire your routes together defines the routing process).

Let's take an actual example, what if we define the following in our application:

  • @RequestMapping with the patterns "/users/{name}", "/something" producing JSON only, and "/**" for the resource handling
  • RouterFunctions with, in order, "/users/{name}", "/something" producing XML only, "/static/**" for the resource handling, and a default handler showing an error page.

No matter how we order/mix both variants, there are many cases where we could argue one way or the other; which handler should take care of a given request? Given the core differences between both ways of routing requests, we can't really blend those into one as one is about patterns specificity and the other about functions.

My current vote is to not support this use case, but I'll let Arjen Poutsma, Sébastien Deleuze and Rossen Stoyanchev comment as well.

@spring-projects-issues
Copy link
Collaborator Author

Brian Clozel commented

TL;DR: this is supported but not actively promoted, since developers have to live with quite a few trade-offs and a good understanding of the Spring WebFlux internals.

Rossen Stoyanchev just pointed me to router functions implementations for HandlerMapping, HandlerAdapter and HandlerResultHandler.

So technically, you can declare a few additional beans in your application configuration - given you've already configured the annotation variant, probably with @EnableWebFlux: see this part.

With that setup, you can use both annotation and functional, but you have to live with the following limitations:

  • all the issues listed above (duplicate routes, same routes with content negotiation variations, having a "catch-all" pattern like "/**" somewhere...) will apply and short-circuit the following routes. In general, you have to be aware of the routes you add in both and prevent clashes.
  • you'll probably have to order RouterFunction HandlerMapping/HandlerAdapter after the annotation-based ones (use the @Order annotation on the @Bean method)
  • this setup probably won't be supported by Spring Boot since this is a rather advanced, tricky configuration and shouldn't be promoted by the team.

Jonathan Borenstein, let us know if that's what you were looking for and how that arrangement works in your application. Thanks!

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Yes the simplest path is probably @EnableWebFlux + HandlerMapping, HandlerAdapter, and HandlerResultHandler beans like the ones from the link Brian put in the previous comment.

In the absence of an @Order on the HandlerMapping bean it should take lowest priority anyway. The ServerResponseResultHandler however should probably be ordered ahead of the other result handlers and in particular ahead of ViewResolutionResultHandler which has some default handling of Object and simple types. The ViewResolutionResultHandler is not explicitly ordered so it's lowest priority so really an explicit order value for ServerResponseResultHandler would be good enough. We probably should have ServerResponseResultHandler implement Ordered to give it a default value.

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 24, 2017

Arjen Poutsma commented

Note that I've just completed work on #20095, which should make it a lot easier to combine controllers and router functions in one app. Just using @EnableWebFlux should be enough, see https://github.com/spring-projects/spring-framework/blob/01e3561db91a06979d9fede8bfaa02519360d6a7/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/DispatcherHandlerIntegrationTests.java

@spring-projects-issues
Copy link
Collaborator Author

Brian Clozel commented

This has been reflected in Spring Boot and as of 2.0.0.M2.

@spring-projects-issues spring-projects-issues added status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement in: web Issues in web modules (web, webmvc, webflux, websocket) labels Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants