#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()
Комментарии:
1. Для list добавление /list в list api ведет себя так же и в этом примере.
2. если вам нужна конкретная разница между
/list
и/list/{value}
, тогда вам нужно выполнить собственную проверку null, существует ли значение или нет, потому что платформа не может определить ваши намерения, хотите ли вы иметь возможность отправлять пустое значение или нет. Это не искусственный интеллект.3. маршруты оцениваются в том порядке, в котором они определены. Если вы хотите
/item/list
сопоставить с уникальной функцией hander, то определите ее над/item/{item_id}
определением маршрута. Хотя, как указано в другом комментарии, это не похоже на restful.