1、概览 {#1概览}
文档是构建任何健壮的 REST API 的重要部分。我们可以基于 OpenAPI 规范实现 API 文档,并在 Spring 应用中使用 Swagger UI 进行可视化展示。
此外,由于 API 端点可以通过 API 网关公开,我们还需要将后端服务的 OpenAPI 文档与网关服务集成。网关服务将提供所有 API 文档的汇总视图。
本文将带你了解如何在 Spring 应用中集成 OpenAPI,以及如何使用 Spring Cloud Gateway 服务公开后端服务的 API 文档。
2、示例应用 {#2示例应用}
假设我们需要构建一个简单的微服务来获取一些数据。
2.1、Maven 依赖 {#21maven-依赖}
首先,添加 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 {#22实现-rest-api}
我们的后端应用有一个端点返回 Product
数据。
首先,创建 Product
类:
public class Product {
private long id;
private String name;
// 标准 Getter / Setter
}
接下来,在 ProductController
中实现 getProduct
端点:
@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 {#3spring-整合-openapi}
OpenAPI 3.0 规范可通过 springdoc-openapi starter 项目与 Spring Boot 3 集成。
3.1、Springdoc 依赖 {#31springdoc-依赖}
Spring Boot 3.x 要求使用 version 2 的 springdoc-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 定义 {#32配置-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 路径 {#33配置-openapi-和-swagger-ui-路径}
OpenAPI 和 Swagger UI 默认路径可通过 springdoc-openapi 配置进行自定义。
在 springdoc-openapi
属性中包含特定于 product 的路径:
springdoc:
api-docs:
enabled: true
path: /product/v3/api-docs
swagger-ui:
enabled: true
path: /product/swagger-ui.html
在任何环境下,我们都可以配置 enabled
为 false
来禁用 OpenAPI 的 api-docs 和 Swagger UI 功能:
springdoc:
api-docs:
enabled: false
swagger-ui:
enabled: false
3.4、添加 API 摘要 {#34添加-api-摘要}
我们可以配置 API 摘要和 Payload 详情,并添加任何与安全相关的信息。
在 ProductController
类中加入 API 操作摘要详情:
@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 操作摘要以及 API 请求和响应参数说明。
后端服务已与 OpenAPI 集成,现在我们将实现一个 API 网关服务。
4、使用 Spring Cloud Gateway 实现网关 {#4使用-spring-cloud-gateway-实现网关}
现在,使用 Spring Cloud Gateway 支持来实现 API 网关服务。API 网关服务将向用户公开 Product API。
4.1、Spring Cloud Gateway 依赖 {#41spring-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 路由 {#42配置-api-路由}
我们可以使用 Spring Cloud Gateway 路由选项公开 Product Service 端点。
使用 /product
路径配置 predicates
,并使用后端 URI http://<hostname>:<port>
设置 uri
属性:
spring:
cloud:
gateway:
routes:
- id: product_service_route
predicates:
- Path=/product/**
uri: http://localhost:8081
在任何生产就绪的应用中,Spring Cloud Gateway 应该路由到后端服务的负载均衡器(Balancer) URL。
4.3、测试 Spring Gateway API {#43测试-spring-gateway-api}
运行 Product 和网关这两个服务:
$ 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
现在,通过网关服务 URL 访问 /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 Service 整合 OpenAPI {#5spring-gateway-service-整合-openapi}
现在,将 Spring Gateway 应用与 OpenAPI 文档整合在一起,就像在 Product 服务中实现的那样。
5.1、springdoc-openapi 依赖 {#51springdoc-openapi-依赖}
这需要添加 springdoc-openapi-starter-webflux-ui
依赖,而不是 springdoc-openapi-starter-webmvc-ui 依赖:
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
<version>2.6.0</version>
</dependency>
注意,Spring Cloud Gateway 需要 webflux-ui 依赖项,因为它基于 Spring WebFlux 项目。
5.2、配置 OpenAPI 定义 {#52配置-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 路径 {#53配置-openapi-和-swagger-ui-路径}
在网关服务中自定义 OpenAPI api-docs.path
和 swagger-ui.urls
属性:
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 引用 {#54包含-openapi-url-引用}
要从网关服务访问 Product 服务 api-docs
端点,需要在上述配置中添加其路径。
在上述 springdoc.swagger-ui.urls
属性中包含 /product/v3/api-docs
路径:
springdoc:
swagger-ui:
urls:
- name: gateway-service
url: /v3/api-docs
- name: product-service
url: /product/v3/api-docs
6、在 API Gateway 应用中测试 Swagger UI {#6在-api-gateway-应用中测试-swagger-ui}
运行这两个应用后,我们可以通过浏览器访问 http://localhost:8080/swagger-ui.html
,在 Swagger UI 中查看 API 文档:
现在,从右上角的下拉菜单中访问 Product 服务 api-docs
:
通过上述页面,我们可以查看并访问 Product 服务 API 端点。
我们可以请求 http://localhost:8080/product/v3/api-docs
端点,以 JSON 格式访问 Product 服务 API 文档。
7、总结 {#7总结}
本文介绍了如何在 Spring 应用中使用 springdoc-openapi 支持来实现 OpenAPI 文档,以及如何在 Spring Cloud Gateway 服务中公开后端 API 文档。
最后,演示了如何通过 Spring Gateway 服务的 Swagger UI 页面访问 OpenAPI 文档。
Ref:https://www.baeldung.com/spring-cloud-gateway-integrate-openapi