Spring Functional Routing
This post is about the clever tricks you can pull with Spring new functional routing and it’s Kotlin DSL.
Spring 5 introduced the Functional Web Framework and with it the ability to do functional routing. Basically instead of annotating your methods with the good old @RequestMapping
you can now write functions that go from a Request
to a Response<T>
(called HandlerFunction<T>
). And then use a RouterFunction<T>
to map which path will end up in which handler.
Now, for the sake of brevity, I won’t talk about all the benefits of this new functional paradigm. Instead I’d like to focus on some things that can be done with functional routing that were not possible before.
I have to admit that at first I wasn’t sold on the functional routing thing. Why would I want to replace @RequestMapping
with 2 different functions? Isn’t that more code to achieve the same goal? For comparison this is how a simple RoutingFunction could look like1:
It’s readable but certainly not as succinct as @GetMapping("/api/users")
. But this terseness comes at the price of expressiveness. Or as this article on Spring.io puts it:
The
RouterFunction
has a similar purpose as a@RequestMapping
annotation. However, there is an important distinction: with the annotation your route is limited to what can be expressed through the annotation values.
Complex routing
I’ll use an example to illustrate some of the things that can be achieved with complex routing. Say I have some data modeling a résumé that contains multiple sections. I want to expose each of this sections as a different REST endpoint. Underneath we need to handle each call the same way, the only difference is that we’d be processing a different section of data. We could do the routing like this:
We can iterate through the enum and create a new mapping for each of the sections with the GET
function. Furthermore the function getSectionHandler
can receive the enum as parameter and use it for handling the response instead of having to rely only on the ServerRequest
context.
Now this is only one of the tricks that can be done with functional routing. Having a Kotlin DSL means we can do any kind of scripting we can think of when defining the routes. As always:
Abusing this feature would make your routing logic a tangled mess, too hard to understand and maintain. So be smart about it.
-
Source: [kotlin-swagger-spring-functional-template][2]↩