How to add OpenAPI/Swagger annotations in a Spring library consumed by Spring Boot apps?

4 weeks ago 18
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 @Tag

These come from:

io.swagger.core.v3:swagger-annotations

This 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-ui

That 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-ui

Why?

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-annotations

And nothing else. Done. Enjoy now!! :-)

Read Entire Article