ARTICLE AD BOX
In your library, you only need:
<dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> <scope>compile</scope> </dependency>You do NOT need:
springdoc-openapi-starter-*
springdoc-openapi-core
Swagger UI
Any SpringDoc runtime dependency
Let the consuming Spring Boot apps provide SpringDoc and Swagger UI.
Your library only needs annotations
You're only adding:
@Operation @Parameter @ApiResponse @Schema @TagThese come from:
io.swagger.core.v3:swagger-annotationsThis dependency:
Is lightweight
Contains only annotation classes
Has no runtime auto-configuration
Does not bring Swagger UI
Does not start SpringDoc
Perfect for a reusable library.
The consuming app already has SpringDoc
The consuming apps include:
org.springdoc:springdoc-openapi-starter-webmvc-uiThat starter:
Scans the Spring context
Detects all @RestControllers
Reads Swagger annotations
Builds the OpenAPI spec
Exposes Swagger UI
Since your library’s controllers are part of the application context, SpringDoc will automatically include them.
You don’t need to do anything extra.
Do NOT add:
org.springdoc:springdoc-openapi-core org.springdoc:springdoc-openapi-starter-webmvc-api org.springdoc:springdoc-openapi-starter-webmvc-uiWhy?
These are runtime components
They register Spring beans
They may conflict with the consuming app
They create version-coupling problems
They break clean library design
Your library should not auto-configure Swagger.
In your library:
<dependency> <groupId>io.swagger.core.v3</groupId> <artifactId>swagger-annotations</artifactId> </dependency>Optionally, you can mark it as:
<optional>true</optional>If you want consumers to control the version completely.
In consuming apps (already done)
<dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> </dependency>Done.
@RestController @RequestMapping("/api/library") @Tag(name = "Library API") public class LibraryController { @Operation(summary = "Get greeting message") @ApiResponse(responseCode = "200", description = "Successful response") @GetMapping("/hello") public String hello() { return "Hello from library"; } }
When the consumer runs the app, this endpoint appears automatically in Swagger UI.
=> Keep your library:
Free of UI
Free of SpringDoc runtime
Only using swagger-annotations
Version-neutral when possible
=> Let the application control:
OpenAPI generation
UI exposure
Customization
Grouping
Security configuration
If your library exposes many APIs, you might want to:
Use consistent @Tag names
Use @Hidden for internal endpoints
Use @Schema on DTOs
Everything will be picked up automatically by SpringDoc in the consuming app.
Use:
io.swagger.core.v3:swagger-annotationsAnd nothing else. Done. Enjoy now!! :-)
