Return to site

🧩📜 OPENAPI 3.1 WITH SPRING BOOT 4: DOCUMENT YOUR API CONTRACT, NOT JUST YOUR CODE

· spring

When you build a REST API with Spring Boot 4, your controllers expose behavior.

But your consumers need something else:

▪️ What endpoints exist?

▪️ What request body is expected?

▪️ What response can be returned?

▪️ What errors are possible?

▪️ How is the API secured?

That is where OpenAPI 3.1 comes in. 🚀

🔸 TL;DR

▪️ OpenAPI 3.1 describes your REST API contract in a standard format.

  1. ▪️ Spring Boot 4 APIs can expose OpenAPI documentation using Springdoc OpenAPI 3.x.
  2. ▪️ Swagger UI is not the specification. It is the visual interface on top of the OpenAPI contract.
  3. ▪️ The most useful parts to document are metadata, operations, schemas, responses, parameters, groups, and security.
  4. ▪️ Good OpenAPI documentation reduces friction between backend, frontend, QA, DevOps, and external consumers.

🔸 WHAT IS OPENAPI?

OpenAPI is a standard, machine-readable description of an HTTP API.

It describes:

  1. ▪️ Paths
  2. ▪️ Operations
  3. ▪️ Parameters
  4. ▪️ Request bodies
  5. ▪️ Responses
  6. ▪️ Schemas
  7. ▪️ Security
  8. ▪️ Metadata

In short:

Your API contract, written in a format tools can understand.

With Spring Boot 4, the common approach is to use Springdoc OpenAPI 3.x to generate the OpenAPI document from your Spring MVC or WebFlux application.

🔸 1. ADD OPENAPI + SWAGGER UI

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>3.0.3</version>
</dependency>
springdoc:
  api-docs:
    version: openapi_3_1
  swagger-ui:
    path: /swagger-ui.html

This enables:

▪️ /v3/api-docs → the OpenAPI JSON contract

▪️ /v3/api-docs.yaml → the YAML version

▪️ /swagger-ui.html → the visual UI for humans

OpenAPI is the contract. Swagger UI is the interactive documentation.

🔸 2. DESCRIBE THE API METADATA

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info;
import org.springframework.context.annotation.Configuration;

@Configuration
@OpenAPIDefinition(
    info = @Info(
        title = "Order API",
        version = "1.0.0",
        description = "REST API for managing customer orders"
    )
)
class OpenApiConfig {
}

This defines the global identity of your API.

Useful for:

▪️ API portals

▪️ Generated clients

▪️ Swagger UI

▪️ External consumers

▪️ Internal platform teams

Without metadata, your API documentation looks technical but unfinished.

🔸 3. DOCUMENT AN ENDPOINT OPERATION

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@Tag(name = "Orders", description = "Operations related to customer orders")
@RestController
@RequestMapping("/api/orders")
class OrderController {

    @Operation(
        summary = "Create an order",
        description = "Creates a new order for an existing customer"
    )
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    OrderResponse createOrder(
        @Valid @RequestBody CreateOrderRequest request
    ) {
        return new OrderResponse("ORD-123", "CREATED");
    }
}

Here you document the path + operation part of OpenAPI.

This helps developers understand:

▪️ What the endpoint does

▪️ Why it exists

▪️ How it should be used

▪️ Which business capability it exposes

Good documentation starts at the controller boundary.

🔸 4. DOCUMENT SCHEMAS WITH VALIDATION

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

@Tag(name = "Orders", description = "Operations related to customer orders")
@RestController
@RequestMapping("/api/orders")
class OrderController {

    @Operation(
        summary = "Create an order",
        description = "Creates a new order for an existing customer"
    )
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    OrderResponse createOrder(
        @Valid @RequestBody CreateOrderRequest request
    ) {
        return new OrderResponse("ORD-123", "CREATED");
    }
}

This is the schema part of OpenAPI.

Springdoc can use your Java model and Jakarta Validation annotations to enrich the generated contract.

That means your DTO becomes more than a Java type.

It becomes documentation.

🔸 5. DOCUMENT RESPONSES CLEARLY

import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;

@ApiResponses({
    @ApiResponse(
        responseCode = "201",
        description = "Order created successfully"
    ),
    @ApiResponse(
        responseCode = "400",
        description = "Invalid request payload"
    ),
    @ApiResponse(
        responseCode = "404",
        description = "Customer not found"
    )
})
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
OrderResponse createOrder(@Valid @RequestBody CreateOrderRequest request) {
    return new OrderResponse("ORD-123", "CREATED");
}

This documents the reality of APIs:

They do not only return 200 OK.

A useful API contract explains both:

▪️ Success cases

▪️ Failure cases

That is especially important for frontend teams, mobile teams, QA, integration partners, and generated clients.

🔸 6. DOCUMENT SECURITY

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.security.SecurityScheme;
import io.swagger.v3.oas.annotations.enums.SecuritySchemeType;
import org.springframework.context.annotation.Configuration;

@Configuration
@SecurityScheme(
    name = "bearerAuth",
    type = SecuritySchemeType.HTTP,
    scheme = "bearer",
    bearerFormat = "JWT"
)
@OpenAPIDefinition(
    security = @SecurityRequirement(name = "bearerAuth")
)
class OpenApiSecurityConfig {
}

This declares that your API uses bearer token authentication.

Important point:

OpenAPI does not secure your API.

Spring Security does.

OpenAPI documents how consumers are expected to authenticate.

🔸 7. SPLIT YOUR API INTO GROUPS

import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
class OpenApiGroupsConfig {

    @Bean
    GroupedOpenApi publicApi() {
        return GroupedOpenApi.builder()
            .group("public")
            .pathsToMatch("/api/public/**")
            .build();
    }

    @Bean
    GroupedOpenApi adminApi() {
        return GroupedOpenApi.builder()
            .group("admin")
            .pathsToMatch("/api/admin/**")
            .build();
    }
}

This is useful when one application exposes multiple API surfaces.

For example:

▪️ Public API

▪️ Admin API

▪️ Partner API

▪️ Internal API

One codebase. Multiple contracts.

🔸 OPENAPI VS SWAGGER

This is where many developers get confused.

▪️ OpenAPI = the specification / contract format

▪️ Swagger UI = a tool to visualize and test that contract

▪️ Swagger Editor = a tool to edit OpenAPI definitions

▪️ Swagger annotations = Java annotations used by libraries like Springdoc

▪️ Springdoc OpenAPI = the Spring Boot integration that generates the contract

So today, it is more precise to say:

“I generate an OpenAPI contract and expose it through Swagger UI.”

Not:

“I added Swagger.”

Swagger is the tooling ecosystem.

OpenAPI is the standard.

🔸 TAKEAWAYS

▪️ Do not treat OpenAPI as “nice documentation”. Treat it as an API contract.

▪️ Keep your DTO validation and schema documentation aligned.

▪️ Document errors as seriously as success responses.

▪️ Use groups when your API has different audiences.

▪️ Remember: OpenAPI documents the API. Spring Security protects it. Swagger UI displays it.

A clean API is not only one that works.

It is one that other developers can understand, test, and integrate without reverse-engineering your code. ☕

#Java #SpringBoot #SpringBoot4 #OpenAPI #OpenAPI31 #Swagger #Springdoc #RESTAPI #BackendDevelopment #APIDesign #SoftwareEngineering #JavaDeveloper

Go further with Java certification:

Java👇

Spring👇

SpringBook👇

JavaBook👇