OpenAPI-Swagger webflux Spring boot 3

I don't know why in my Swagger, I see only one of my two routes
@Configuration
public class IngredientRouter {

private static final String BASE_URL = "/ingredient/";

@RouterOperations({
@RouterOperation(path = BASE_URL, method = RequestMethod.GET, beanClass = IngredientService.class, beanMethod = "getAllIngredients"),
@RouterOperation(path = BASE_URL + "{name}", method = RequestMethod.GET,beanClass = IngredientService.class, beanMethod = "getAllIngredientsStartingWith")
})
@Bean
public RouterFunction<ServerResponse> ingredientRoute(IngredientHandler handler) {
return RouterFunctions
.route(GET(BASE_URL).and(accept(MediaType.APPLICATION_JSON)), handler::getAllIngredients)
.andRoute(GET(BASE_URL + "{name}").and(accept(MediaType.APPLICATION_JSON)), handler::getAllIngredientsStartingWith);
}
@Configuration
public class IngredientRouter {

private static final String BASE_URL = "/ingredient/";

@RouterOperations({
@RouterOperation(path = BASE_URL, method = RequestMethod.GET, beanClass = IngredientService.class, beanMethod = "getAllIngredients"),
@RouterOperation(path = BASE_URL + "{name}", method = RequestMethod.GET,beanClass = IngredientService.class, beanMethod = "getAllIngredientsStartingWith")
})
@Bean
public RouterFunction<ServerResponse> ingredientRoute(IngredientHandler handler) {
return RouterFunctions
.route(GET(BASE_URL).and(accept(MediaType.APPLICATION_JSON)), handler::getAllIngredients)
.andRoute(GET(BASE_URL + "{name}").and(accept(MediaType.APPLICATION_JSON)), handler::getAllIngredientsStartingWith);
}
31 Replies
JavaBot
JavaBot11mo ago
This post has been reserved for your question.
Hey @Santo! Please use /close or the Close Post button above when your problem is solved. Please remember to follow the help guidelines. This post will be automatically closed after 300 minutes of inactivity.
TIP: Narrow down your issue to simple and precise questions to maximize the chance that others will reply in here. 💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
Santo
SantoOP11mo ago
Any idea please ? 😦
JavaBot
JavaBot11mo ago
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
💤 Post marked as dormant
This post has been inactive for over 300 minutes, thus, it has been archived. If your question was not answered yet, feel free to re-open this post or create a new one. In case your post is not getting any attention, you can try to use /help ping. Warning: abusing this will result in moderative actions taken against you.
dan1st
dan1st11mo ago
Can you show the corresponding controllers? what exactly does it show?
Santo
SantoOP11mo ago
You can find the source code here : https://github.com/Hunikel/Cocktail-API This is the router (equivalent to Controllers from what I understood with ReactiveProgramming) : https://github.com/Hunikel/Cocktail-API/blob/main/src/main/java/com/santo/cocktail/router/IngredientRouter.java
dan1st
dan1st11mo ago
Where did you specify the endpoints?
Santo
SantoOP11mo ago
RouterFunctions.route(GET(BASE_URL) ... Apparently this is the way today for reactive programming and endpoint declaration
dan1st
dan1st11mo ago
oh ok And what does the swagger UI look like?
Santo
SantoOP11mo ago
No description
Santo
SantoOP11mo ago
it seems to detect only one route
dan1st
dan1st11mo ago
which route are you missing? /ingredient?
@Configuration
public class IngredientRouter {

private static final String BASE_URL = "/ingredient";//I removed a / here

@RouterOperations({
@RouterOperation(path = BASE_URL, method = RequestMethod.GET, beanClass = IngredientService.class, beanMethod = "getAllIngredients"),
@RouterOperation(path = BASE_URL + "{name}", method = RequestMethod.GET,beanClass = IngredientService.class, beanMethod = "getAllIngredientsStartingWith")
})
@Bean
public RouterFunction<ServerResponse> ingredientRoute(IngredientHandler handler) {
return RouterFunctions
.route(GET(BASE_URL).and(accept(MediaType.APPLICATION_JSON)), handler::getAllIngredients)
.andRoute(GET(BASE_URL + "/{name}").and(accept(MediaType.APPLICATION_JSON)), handler::getAllIngredientsStartingWith);//I added a /here
}
@Configuration
public class IngredientRouter {

private static final String BASE_URL = "/ingredient";//I removed a / here

@RouterOperations({
@RouterOperation(path = BASE_URL, method = RequestMethod.GET, beanClass = IngredientService.class, beanMethod = "getAllIngredients"),
@RouterOperation(path = BASE_URL + "{name}", method = RequestMethod.GET,beanClass = IngredientService.class, beanMethod = "getAllIngredientsStartingWith")
})
@Bean
public RouterFunction<ServerResponse> ingredientRoute(IngredientHandler handler) {
return RouterFunctions
.route(GET(BASE_URL).and(accept(MediaType.APPLICATION_JSON)), handler::getAllIngredients)
.andRoute(GET(BASE_URL + "/{name}").and(accept(MediaType.APPLICATION_JSON)), handler::getAllIngredientsStartingWith);//I added a /here
}
Does that change anything?
Santo
SantoOP11mo ago
It miss all the other routes
No description
dan1st
dan1st11mo ago
I changed .andRoute(GET(BASE_URL + "{name}"). to .andRoute(GET(BASE_URL + "/{name}"). What if you completely remove the andRoute line (except the ;)?
Santo
SantoOP11mo ago
No description
Santo
SantoOP11mo ago
The swagger doesn't automatically detect the routes, I have to use the @Operation for it to detect it I'm pretty sad with this compared to when the detection was automatic with RestController :/ https://springdoc.org/features.html I tried their way here :
@RouterOperations({ @RouterOperation(path = "/getAllPersons", beanClass = PersonService.class, beanMethod = "getAll"),
@RouterOperation(path = "/getPerson/{id}", beanClass = PersonService.class, beanMethod = "getById"),
@RouterOperation(path = "/createPerson", beanClass = PersonService.class, beanMethod = "save"),
@RouterOperation(path = "/deletePerson/{id}", beanClass = PersonService.class, beanMethod = "delete") })
@Bean
public RouterFunction<ServerResponse> personRoute(PersonHandler handler) {
return RouterFunctions
.route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll)
.andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById)
.andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save)
.andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete);
}
@RouterOperations({ @RouterOperation(path = "/getAllPersons", beanClass = PersonService.class, beanMethod = "getAll"),
@RouterOperation(path = "/getPerson/{id}", beanClass = PersonService.class, beanMethod = "getById"),
@RouterOperation(path = "/createPerson", beanClass = PersonService.class, beanMethod = "save"),
@RouterOperation(path = "/deletePerson/{id}", beanClass = PersonService.class, beanMethod = "delete") })
@Bean
public RouterFunction<ServerResponse> personRoute(PersonHandler handler) {
return RouterFunctions
.route(GET("/getAllPersons").and(accept(MediaType.APPLICATION_JSON)), handler::findAll)
.andRoute(GET("/getPerson/{id}").and(accept(MediaType.APPLICATION_STREAM_JSON)), handler::findById)
.andRoute(POST("/createPerson").and(accept(MediaType.APPLICATION_JSON)), handler::save)
.andRoute(DELETE("/deletePerson/{id}").and(accept(MediaType.APPLICATION_JSON)), handler::delete);
}
dan1st
dan1st11mo ago
Stack Overflow
How to use OpenApi annotations in spring-webflux RouterFunction end...
I am currently working on a project where I use spring functional web programming. I usually use annotations of swagger 2 in restController but with functional web programming I can not find where ...
dan1st
dan1st11mo ago
Does it work without RouterOperations or not?
Santo
SantoOP11mo ago
no, even separating the RouterFunctions into multiple methods with a routeroperation each, the problem persists
dan1st
dan1st11mo ago
Maybe you need to seet an operationId
dan1st
dan1st11mo ago
OpenAPI 3 Library for spring-boot
OpenAPI 3 Library for spring-boot
Library for OpenAPI 3 with spring boot projects. Is based on swagger-ui, to display the OpenAPI description.Generates automatically the OpenAPI file.
Santo
SantoOP11mo ago
it's already there :
@RouterOperation(path = BASE_URL, produces = {MediaType.APPLICATION_JSON_VALUE}, method = RequestMethod.GET, beanClass = IngredientService.class, beanMethod = "getAllIngredients",
operation = @Operation(operationId = "getAllIngredients", responses = {
@ApiResponse(responseCode = "200", description = "successful operation", content = @Content(schema = @Schema(implementation = Ingredient.class)))})),
@RouterOperation(path = BASE_URL, produces = {MediaType.APPLICATION_JSON_VALUE}, method = RequestMethod.GET, beanClass = IngredientService.class, beanMethod = "getAllIngredients",
operation = @Operation(operationId = "getAllIngredients", responses = {
@ApiResponse(responseCode = "200", description = "successful operation", content = @Content(schema = @Schema(implementation = Ingredient.class)))})),
dan1st
dan1st11mo ago
And does it work properly with the annotation present?
Santo
SantoOP11mo ago
nope Maybe it's a bug ... i'll try downgrading the version
dan1st
dan1st11mo ago
GitHub
springdoc-openapi-demos/springdoc-openapi-spring-boot-2-webflux/src...
Demo for OpenAPI 3 with spring-boot. Contribute to springdoc/springdoc-openapi-demos development by creating an account on GitHub.
dan1st
dan1st11mo ago
If you completely remove the second route, does the first one show up?
Santo
SantoOP11mo ago
this is the recommanded way for spring boot 3 😅 but yeah i'll try if i remove the second route the first one shows up yeah
dan1st
dan1st11mo ago
Do you have different operationIds for both routes?
Santo
SantoOP11mo ago
yes
dan1st
dan1st11mo ago
maybe try specifying the method inside the Operation as well
Santo
SantoOP11mo ago
Found the culprit ... I removed the following (beanClass and beanMethod everywhere) and now everything shows
beanClass = IngredientService.class, beanMethod = "getAllIngredients"
beanClass = IngredientService.class, beanMethod = "getAllIngredients"
Idk why ... normally that's what's written in the doc, or it's not up to date
JavaBot
JavaBot11mo ago
Post Closed
This post has been closed by <@231028402025529344>.
Want results from more Discord servers?
Add your server