嵌套的 webflux 路由总是和最上面的路由一起走

Nested webflux routing always goes with the route on the top

任何人都可以告诉我在这个路由示例中每次我输入 ex: /api/person/1 等它都去 /api/person 吗?无论我选择哪种方法,它总是伴随着 /api/person.

@Bean
    public RouterFunction<ServerResponse> monoRouterFunction(PersonService personService) {

      return  RouterFunctions
                .nest(path("/api/person"),
                        route(method(GET), personService::findAllPeople)
                            .andRoute(GET("/{id}"), personService::findOnePerson)
                            .andRoute(POST("/add"), personService::addPerson)
                            .andRoute(PUT("/update"), personService::updatePerson)
                            .andRoute(DELETE("/delete/{id}"), personService::deletePerson));

}

与注释模型不同,WebFlux.fn 对路由非常明确:排序和所有谓词都很重要。但好处是它更容易调试,您可以在谓词中设置调试点以了解为什么将请求路由到处理程序。

在这种情况下,这个 RouterFunction 可以描述为:

如果路径以“/api/person”开头,

  1. 方法是 GET -> 然后 personService::findAllPeople
  2. 方法是 POST 并且路径匹配“/api/person/{id}” -> 然后是 personService::findOnePerson
  3. 等等

因为第一场比赛获胜,所以像 "GET /api/person/42" 这样的请求将匹配 1),因为它以 "/api/person" 开头并且是 GET 请求。

如果你想改变它,你可以改变你的路线顺序,或者改变你的谓词 route(GET("/"), personService::findAllPeople)

以下代码运行良好。我在我的本地亲自尝试过。正如@Brain 所说,只需为 findAllPeople() 处理程序方法添加 GET("/")。

@Bean
public RouterFunction<ServerResponse> monoRouterFunction(PersonService personService) 
{

 return  RouterFunctions
            .nest(path("/api/person"),
                    route(method(GET("/")), personService::findAllPeople)
                        .andRoute(GET("/{id}"), personService::findOnePerson)
                        .andRoute(POST("/add"), personService::addPerson)
                        .andRoute(PUT("/update"), personService::updatePerson)
                        .andRoute(DELETE("/delete/{id}"), personService::deletePerson));

}

示例工作应用程序:https://github.com/karthikaiselvan/spring-reactive-mongo

即使我们可以删除静态导入,此外,如果我们有不同类型的媒体类型,我们可以像下面的代码一样使用 requestPredicate :

 RouterFunction<ServerResponse> json = route()
      .nest(accept(APPLICATION_JSON), builder -> builder
        .GET("/{id}", personHandler::findOnePerson)
        .GET("", personHandler::findAllPeople)).build();

    RouterFunction<ServerResponse> html = route()
      .nest(accept(TEXT_HTML), builder -> builder
        .GET("/{id}", personHandler::renderPerson)
        .GET("", personHandler::renderPersons)).build();

return route()
      .path("api/person", () -> html.and(json)) // the default would be the first one(here is html)
      .build();

您可以在我的存储库中找到更多详细信息:https://github.com/minarashidi/webflux