使用 Spring RouterFunctionDsl 的可组合路由

Composable routing with Spring RouterFunctionDsl

我正在尝试编写更多可组合的 RouterFunctions,其中路由细节被抽象为个人 类。我仍然希望能够在我的应用程序的根目录下有一个 myRoutes 函数。

这可能吗?如果是这样,它的语法是什么样的?

当前状态

@Bean
fun myRoutes(): RouterFunction<ServerResponse> {
    return router {
        "/base-url".nest {
            "/thing-one".nest {
                GET("/", ::getThingOne)
            }
            "/thing-two".nest {
                GET("/", ::getThingTwo)
            }
        }
    }
}

fun getThingOne(serverRequest: ServerRequest): Mono<ServerResponse> {
    return Mono.empty<ServerResponse>()
}

fun getThingTwo(serverRequest: ServerRequest): Mono<ServerResponse> {
    return Mono.empty<ServerResponse>()
}

期望状态

@Bean
fun myRoutes(): RouterFunction<ServerResponse> {
    return router {
        "/base-url".nest {
            ThingOneClass.getRouting()
            ThingTwoClass.getRouting()
        }
    }
}

object ThingOneClass {
    fun getRouting() {
        "/thing-one".nest {
            GET("/", ::getThingOne)
        }
    }

    fun getThingOne(serverRequest: ServerRequest): Mono<ServerResponse> {
        return Mono.empty<ServerResponse>()
    }
}

object ThingTwoClass {
    fun getRouting() {
        "/thing-two".nest {
            GET("/", ::getThingTwo)
        }
    }

    fun getThingTwo(serverRequest: ServerRequest): Mono<ServerResponse> {
        return Mono.empty<ServerResponse>()
    }
}

我想出了如何做到这一点。抽象路由对象中的方法必须return一个符合RouterFunctionDsl.() -> Unit的函数然后需要调用该函数(().invoke(this)

@Bean
fun myRoutes(): RouterFunction<ServerResponse> {
    return router {
        "/base-url".nest {
            // Option 1 `.invoke(this)`
            ThingTwoClass.getRouting().invoke(this)
            // Option 2 `()` - implicitly call invoke(this)
            ThingOneClass.getRouting()()
        }
    }
}

object ThingOneClass {
    fun getRouting(): RouterFunctionDsl.() -> Unit {
        return {
            "/thing-one".nest {
                GET("/", ::getThingOne)
            }
        }
    }

    fun getThingOne(serverRequest: ServerRequest): Mono<ServerResponse> {
        return Mono.empty<ServerResponse>()
    }
}

object ThingTwoClass {
    fun getRouting(): RouterFunctionDsl.() -> Unit {
        return {
            "/thing-two".nest {
                GET("/", ::getThingTwo)
            }
        }
    }

    fun getThingTwo(serverRequest: ServerRequest): Mono<ServerResponse> {
        return Mono.empty<ServerResponse>()
    }
}