1. Overview

Documentation is an essential part of building any robust REST APIs. We can implement API documentation based on the OpenAPI specification and visualize that in Swagger UI in Spring application.

Also, as the API endpoints can be exposed using an API Gateway, we also need to integrate the backend service’s OpenAPI documentation with the gateway service. The gateway service will provide a consolidated view of all the API documentation.

In this article, we’ll learn how to integrate OpenAPI in a Spring application. Also, we’ll expose the backend service’s API documentation using the Spring Cloud Gateway service.

2. Example Application

Let’s imagine we need to build a simple microservice to fetch some data.

2.1. Maven Dependency

First, we’ll include the spring-boot-starter-web dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>3.3.2</version>
</dependency>

2.2. Implement a REST API

Our backend application will have an endpoint to return Product data.

First, let’s model the Product class:

public class Product {
    private long id;
    private String name;
    //standard getters and setters
}

Next, we’ll implement the ProductController with the getProduct endpoint:

@GetMapping(path = "/product/{id}")
public Product getProduct(@PathVariable("id") long productId){
    LOGGER.info("Getting Product Details for Product Id {}", productId);
    return productMap.get(productId);
}

3. Integrate the Spring Application With OpenAPI

OpenAPI 3.0 specification can be integrated with Spring Boot 3 using the springdoc-openapi starter project.

3.1. Springdoc Dependency

Spring Boot 3.x requires that we use version 2 of springdoc-openapi-starter-webmvc-ui dependency:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.6.0</version>
</dependency>

3.2. Configure the OpenAPI Definition

We can customize the OpenAPI definition details like title, description, and version with a few swagger annotations.

We’ll configure the @OpenAPI bean with a few properties, and set the @OpenAPIDefinition annotation:

@OpenAPIDefinition
@Configuration
public class OpenAPIConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
          .servers(List.of(new Server().url("http://localhost:8080")))
          .info(new Info().title("Product Service API").version("1.0.0"));
    }
}

3.3. Configure the OpenAPI and Swagger UI Paths

The OpenAPI and Swagger UI default paths can be customized with the springdoc-openapi configurations.

We’ll include the Product-specific path in the springdoc-openapi properties:

springdoc:
  api-docs:
    enabled: true 
    path: /product/v3/api-docs
  swagger-ui:
    enabled: true
    path: /product/swagger-ui.html

We can disable the OpenAPI’s api-docs and Swagger UI feature in any environment by using the enabled flag as false:

springdoc:
  api-docs:
    enabled: false
  swagger-ui:
    enabled: false

3.4. Adding the API Summary

We can document the API summary, and payload details and include any security-related information.

Let’s include the API operation summary details in the ProductController class:

@Operation(summary = "Get a product by its id")
    @ApiResponses(value = {
      @ApiResponse(responseCode = "200", description = "Found the product",
        content = { @Content(mediaType = "application/json", 
          schema = @Schema(implementation = Product.class)) }),
      @ApiResponse(responseCode = "400", description = "Invalid id supplied",
        content = @Content),
      @ApiResponse(responseCode = "404", description = "Product not found",
        content = @Content) })
@GetMapping(path = "/product/{id}")
public Product getProduct(@Parameter(description = "id of product to be searched") 
  @PathVariable("id") long productId){

In the above code, we’re setting the API operation summary as well as API request and response parameter descriptions.

As the backend service is integrated with OpenAPI, now we’ll implement an API gateway service.

4. Implement the API Gateway With Spring Cloud Gateway

Now let’s implement an API gateway service using the Spring Cloud Gateway support. The API gateway service will expose the Product API to our users.

4.1. Spring Cloud Gateway Dependency

First, we’ll include the spring-cloud-starter-gateway dependency:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
    <version>4.1.5</version
</dependency>

4.2. Configure the API Routing

We can expose the Product service endpoint using the Spring Cloud Gateway routing option.

We’ll configure the predicates with the /product path, and set the uri property with the backend URI http://::

spring:
  cloud:
    gateway:
      routes:
        -   id: product_service_route
            predicates:
              - Path=/product/**
            uri: http://localhost:8081

We should note in any production-ready application, the Spring Cloud Gateway should route to the load balancer URL of the backend service.

4.3. Test the Spring Gateway API

Let’s run both services, Product and Gateway:

$ java -jar ./spring-backend-service/target/spring-backend-service-1.0.0-SNAPSHOT.jar
$ java -jar ./spring-cloud-gateway-service/target/spring-cloud-gateway-service-1.0.0-SNAPSHOT.jar

Now, let’s access the /product endpoint using the gateway service URL:

$ curl -v 'http://localhost:8080/product/100001'
< HTTP/1.1 200 OK
< Content-Type: application/json
{"id":100001,"name":"Apple"}

As tested above, we’re able to get the backend API response.

5. Integrate the Spring Gateway Service With OpenAPI

Now we can integrate the Spring Gateway application with the OpenAPI documentation as done in the Product service.

5.1. springdoc-openapi Dependency

We’ll include the springdoc-openapi-starter-webflux-ui dependency instead of the springdoc-openapi-starter-webmvc-ui dependency:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
    <version>2.6.0</version>
</dependency>

We should note that the Spring Cloud Gateway requires the webflux-ui dependency because it’s based on the Spring WebFlux project.

5.2. Configure the OpenAPI Definition

Let’s configure an OpenAPI bean with a few summary-related details:

@OpenAPIDefinition
@Configuration
public class OpenAPIConfig {

    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI().info(new Info()
          .title("API Gateway Service")
          .description("API Gateway Service")
          .version("1.0.0"));
    }
}

5.3. Configure the OpenAPI and Swagger UI Paths

We’ll customize the OpenAPI api-docs.path and swagger-ui.urls property in the Gateway service:

springdoc:
  api-docs:
    enabled: true
    path: /v3/api-docs
  swagger-ui:
    enabled: true
    config-url: /v3/api-docs/swagger-config
    urls:
      -   name: gateway-service
          url: /v3/api-docs

5.4. Include the OpenAPI URL Reference

To access the Product service api-docs endpoint from the Gateway service, we’ll need to add its path in the above configuration.

We’ll include the /product/v3/api-docs path in the above springdoc.swagger-ui.urls property:

springdoc:
  swagger-ui:
    urls:
      -   name: gateway-service
          url: /v3/api-docs
      -   name: product-service
          url: /product/v3/api-docs

6. Test the Swagger UI in API Gateway Application

When we run both applications, we can view the API documentation in Swagger UI by navigating to http://localhost:8080/swagger-ui.html:

Gateway_Swagger_UI

Now, we’ll access the Product service api-docs from the top right corner dropdown:

Product_Service_OpenAPI_Defination

From the above page, we can view and access the Product service API endpoint.

We can access the Product service API documentation in a JSON format by accessing http://localhost:8080/product/v3/api-docs.

7. Conclusion

In this article, we’ve learned how to implement OpenAPI documentation in a Spring application using springdoc-openapi support.

We’ve also seen how to expose the backend API in the Spring Cloud Gateway service.

Finally, we’ve demonstrated how to access the OpenAPI documentation with the Spring Gateway service Swagger UI page.

As always, the example code can be found over on GitHub.