1. 概述

文档是构建健壮REST API的关键环节。在Spring应用中,我们可以基于OpenAPI规范实现API文档,并通过Swagger UI进行可视化展示。

当API接口通过API网关暴露时,我们还需要将后端服务的OpenAPI文档与网关服务集成。网关服务将提供所有API文档的统一视图。

本文将学习如何在Spring应用中集成OpenAPI,并通过Spring Cloud Gateway服务暴露后端服务的API文档。

2. 示例应用

假设我们需要构建一个简单的微服务来获取数据。

2.1 Maven依赖

首先添加spring-boot-starter-web依赖:

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

2.2 实现REST API

后端应用将包含一个返回Product数据的接口。

先定义Product类:

public class Product {
    private long id;
    private String name;
    //标准getter和setter
}

然后实现ProductControllergetProduct接口:

@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. 在Spring应用中集成OpenAPI

使用springdoc-openapi starter项目可以在Spring Boot 3中集成OpenAPI 3.0规范。

3.1 Springdoc依赖

Spring Boot 3.x需要使用版本2springdoc-openapi-starter-webmvc-ui依赖:

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

3.2 配置OpenAPI定义

通过几个Swagger注解自定义OpenAPI定义的标题、描述和版本等信息。

配置@OpenAPI bean并设置@OpenAPIDefinition注解:

@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 配置OpenAPI和Swagger UI路径

通过springdoc-openapi配置自定义默认路径:

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

⚠️ 环境控制:可通过设置enabled: false在任何环境中禁用OpenAPI功能:

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

3.4 添加API摘要

可以记录API摘要、负载详情和安全相关信息。

ProductController中添加操作摘要:

@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){

上述代码设置了API操作摘要以及请求/响应参数描述。

后端服务已集成OpenAPI,接下来实现API网关服务。

4. 使用Spring Cloud Gateway实现API网关

现在使用Spring Cloud Gateway实现API网关服务,该服务将向用户暴露Product API。

4.1 Spring Cloud Gateway依赖

添加spring-cloud-starter-gateway依赖:

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

4.2 配置API路由

通过Spring Cloud Gateway的路由选项暴露Product服务接口。

配置predicates/product路径,设置uri为后端服务地址:

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

⚠️ 生产环境注意:生产环境中Spring Cloud Gateway应路由到后端服务的负载均衡器URL。

4.3 测试Spring Gateway API

启动Product和Gateway服务:

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

通过网关访问/product接口:

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

测试成功获取后端API响应。

5. 在Spring Gateway服务中集成OpenAPI

现在像Product服务一样,在Spring Gateway应用中集成OpenAPI文档。

5.1 springdoc-openapi依赖

使用springdoc-openapi-starter-webflux-ui替代webmvc-ui依赖:

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

⚠️ 依赖选择:Spring Cloud Gateway基于Spring WebFlux,必须使用webflux-ui依赖。

5.2 配置OpenAPI定义

配置包含摘要信息的OpenAPI bean:

@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 配置OpenAPI和Swagger UI路径

在Gateway服务中自定义路径:

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 添加OpenAPI URL引用

在Gateway服务中访问Product服务的api-docs端点,需在配置中添加其路径:

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

6. 测试API网关中的Swagger UI

启动两个应用后,访问http://localhost:8080/swagger-ui.html查看API文档

Gateway_Swagger_UI

从右上角下拉菜单选择Product服务:

Product_Service_OpenAPI_Defination

在此页面可查看和访问Product服务的API接口。

通过访问http://localhost:8080/product/v3/api-docs可获取JSON格式的API文档

7. 总结

本文学习了如何使用springdoc-openapi在Spring应用中实现OpenAPI文档,以及如何通过Spring Cloud Gateway暴露后端API。

最后演示了如何通过Spring Gateway的Swagger UI页面访问OpenAPI文档。

关键收获

  • OpenAPI集成简化了API文档管理
  • 网关统一文档视图提升开发效率
  • 环境隔离配置避免生产环境暴露

示例代码可在GitHub获取。


原始标题:Integrate OpenAPI With Spring Cloud Gateway | Baeldung