Spring webflux — Маршрутизация

#java #spring-boot #spring-webflux

#java #весенняя загрузка #spring-webflux

Вопрос:

Я использую Spring boot 2.3.3.RELASE и использую webflux. Используя приведенную ниже конфигурацию маршрутизатора.

 @Bean
public RouterFunction<ServerResponse> itemRoute() {
    return RouterFunctions.route(POST("/api/v1/item").and(accept(APPLICATION_JSON)), itemHandler::createItem)
            .andRoute(GET("/api/v1/item/{itemId}").and(accept(APPLICATION_JSON)), itemHandler::getItemById)
            .andRoute(GET("/api/v1/item/list").and(accept(APPLICATION_JSON)), itemHandler::getItems);
}
  

Когда я нажимаю /api/v1/item/1 —> Это работает так, как ожидалось.

Но нажатие /api/v1/list также переходит в getItemById вместо getItems . /api/v1/item/list также рассматривается как /api/v1/item/{itemId} , и список отображается как ItemId.

Что-нибудь не так с этим?

Комментарии:

1. зачем вам нужно /list указывать URL в конце? Не следует /api/v1/item возвращать список всех элементов, если вы следуете дизайну restful api?

Ответ №1:

Документация Spring для andRoute

Возвращает составную функцию маршрутизации, которая направляет к заданной функции-обработчику, если этот маршрут не совпадает и применяется данный предикат запроса.

Ключевое слово здесь — составленный. Это означает, что вы можете объявить несколько маршрутов, которые все вместе должны совпадать для запуска маршрута.

то, что вы ищете, вероятно, просто использует простую route функцию builder.

Взят пример из документации spring:

 RouterFunction<ServerResponse> route = route()
    .GET("/person/{id}", accept(APPLICATION_JSON), handler::getPerson) 
    .GET("/person", accept(APPLICATION_JSON), handler::listPeople) 
    .POST("/person", handler::createPerson) 
    .add(otherRoute) 
    .build();
  

или вы могли бы использовать path функцию builder — другой вариант.

 RouterFunction<ServerResponse> route = route()
        .path("/api/person", builder -> builder
            .POST( ...)
            .GET( ... )
            .GET( ... )
        ).build())
    .build()
  

Функция маршрутизатора Webflux

Комментарии:

1. Для list добавление /list в list api ведет себя так же и в этом примере.

2. если вам нужна конкретная разница между /list и /list/{value} , тогда вам нужно выполнить собственную проверку null, существует ли значение или нет, потому что платформа не может определить ваши намерения, хотите ли вы иметь возможность отправлять пустое значение или нет. Это не искусственный интеллект.

3. маршруты оцениваются в том порядке, в котором они определены. Если вы хотите /item/list сопоставить с уникальной функцией hander, то определите ее над /item/{item_id} определением маршрута. Хотя, как указано в другом комментарии, это не похоже на restful.