在文章集成SWAGGER2服務-spring cloud 入門教程中我們學習了使用swagger2來生成微服務的文檔方法。但SpringFox 庫最重要的問題是缺乏對最新版本 3 中的 OpenAPI 和 Spring 的支持使用 WebFlux 構建的反應式 API。所有這些特性都是由Springdoc OpenAPI 庫實現的。因此,它可能會取代 SpringFox 作為 Swagger 和用於 Spring Boot 應用程序的 OpenAPI 3 生成工具。
例子
作為本文中的代碼示例,我們將使用使用 Spring Cloud 構建的典型微服務架構。它由 Spring Cloud Config Server、Eureka 發現和作為 API 網關的 Spring Cloud Gateway 組成。我們還有三個微服務,外部客戶端只能通過網關才能訪問它們暴露 REST API 。下圖顯示了本文所提及的系統簡單架構圖。
執行
與 Springdoc OpenAPI 庫相關的第一個好消息是它可以與 SpringFox 庫一起存在而不會發生任何沖突。如果有人使用您的 Swagger 文檔,要為基於標准 Spring MVC 的應用程序啟用 Springdoc,您需要將以下依賴項包含到 Maven 中pom.xml
。
1
2
3
4
5
|
<
dependency
>
<
groupId
>org.springdoc</
groupId
>
<
artifactId
>springdoc-openapi-webmvc-core</
artifactId
>
<
version
>1.2.32</
version
>
</
dependency
>
|
我們的每個 Spring Boot 微服務都構建在 Spring MVC 之上,並為標准同步 REST 通信提供端點。但是,構建在 Spring Cloud Gateway 之上的 API 網關使用 Netty 作為嵌入式服務器,並基於響應式 Spring WebFlux。它還提供 Swagger UI 以訪問所有微服務公開的文檔,因此它必須包含啟用 UI 的庫。必須包含以下兩個庫才能為基於 Spring WebFlux 的響應式應用程序啟用 Springdoc 支持。
1
2
3
4
5
6
7
8
9
10
|
<
dependency
>
<
groupId
>org.springdoc</
groupId
>
<
artifactId
>springdoc-openapi-webflux-core</
artifactId
>
<
version
>1.2.31</
version
>
</
dependency
>
<
dependency
>
<
groupId
>org.springdoc</
groupId
>
<
artifactId
>springdoc-openapi-webflux-ui</
artifactId
>
<
version
>1.2.31</
version
>
</
dependency
>
|
我們可以通過在 Spring Boot 配置文件中設置屬性或使用@Beans
. 例如,我們不想為應用程序公開的所有 HTTP 端點(如 Spring 特定端點)生成 OpenAPI 清單,因此我們可以定義一個基本包屬性用於掃描,如下所示。在我們的源代碼示例中,每個應用程序 YAML 配置文件都位於config-service模塊中。
1
2
|
springdoc:
packagesToScan: pl.piomin.services.department
|
這是員工服務的主要類。我們使用@OpenAPIDefinition
注釋來定義 Swagger 站點上顯示的應用程序的描述。如您所見,我們仍然可以使用@EnableSwagger2
.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@SpringBootApplication
@EnableDiscoveryClient
@EnableSwagger2
@OpenAPIDefinition
(info =
@Info
(title =
"Employee API"
, version =
"1.0"
, description =
"Documentation Employee API v1.0"
)
)
public
class
EmployeeApplication {
public
static
void
main(String[] args) {
SpringApplication.run(EmployeeApplication.
class
, args);
}
}
|
一旦您啟動每個微服務,它將公開端點/v3/api-docs
。我們可以通過使用springdoc.api-docs.path
Spring 配置文件中的屬性來自定義該上下文。由於不是必須的,我們可以繼續在 Spring Cloud Gateway 上實現。Springdoc 沒有提供與 SpringFox 類似的類SwaggerResource
,它在上一篇文章中用於暴露來自不同微服務的多個 API。幸運的是,有一種分組機制允許將 OpenAPI 定義分成具有給定名稱的不同組。要使用它,我們需要聲明一個GroupOpenAPI
bean列表。
這是網關服務中負責創建由網關處理的 OpenAPI 資源列表的代碼片段。首先,我們使用RouteDefinitionLocator
豆。然后我們獲取每個路由的 id 並將其設置為組名。因此,我們在 path 下有多個 OpenAPI 資源/v3/api-docs/{SERVICE_NAME}
,例如/v3/api-docs/employee
。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@Autowired
RouteDefinitionLocator locator;
@Bean
public
List<GroupedOpenApi> apis() {
List<GroupedOpenApi> groups =
new
ArrayList<>();
List<RouteDefinition> definitions = locator.getRouteDefinitions().collectList().block();
definitions.stream().filter(routeDefinition -> routeDefinition.getId().matches(
".*-service"
)).forEach(routeDefinition -> {
String name = routeDefinition.getId().replaceAll(
"-service"
,
""
);
GroupedOpenApi.builder().pathsToMatch(
"/"
+ name +
"/**"
).setGroup(name).build();
});
return
groups;
}
|
API 路徑 like/v3/api-docs/{SERVICE_NAME}
並不是我們想要實現的,因為我們到下游服務的路由是基於從發現中獲取的服務名稱。因此,如果您調用 address 就像http://localhost:8060/employee/**
它會在employee-service
. 這是網關服務配置中的路由定義。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
spring:
cloud:
gateway:
discovery:
locator:
enabled:
true
routes:
- id: employee-service
uri: lb:
//employee-service
predicates:
- Path=/employee/**
filters:
- RewritePath=/employee/(?<path>.*), /$\{path}
- id: department-service
uri: lb:
//department-service
predicates:
- Path=/department/**
filters:
- RewritePath=/department/(?<path>.*), /$\{path}
- id: organization-service
uri: lb:
//organization-service
predicates:
- Path=/organization/**
filters:
- RewritePath=/organization/(?<path>.*), /$\{path}
|
由於 Springdoc 不允許自定義分組機制的默認行為來更改生成的路徑,因此我們需要提供一些解決方法。我的提議只是在專用於 Open API 路徑處理的網關配置中添加一個新的路由定義。它將路徑重寫/v3/api-docs/{SERVICE_NAME}
為/{SERVICE_NAME}/v3/api-docs
,由另一個負責與 Eureka 發現交互的路由處理。
1
2
3
4
5
6
|
- id: openapi
uri: http:
//localhost:${server.port}
predicates:
- Path=/v3/api-docs/**
filters:
- RewritePath=/v3/api-docs/(?<path>.*), /$\{path}/v3/api-docs
|
測試
為了測試我們的簡單示例,我們需要運行所有微服務、配置服務器、發現和網關。微服務在動態生成的端口下可用,配置服務器在 下可用8888
,發現在 下8061
,網關在 下8060
。我們可以通過調用訪問每個微服務http://localhost:8060/{SERVICE_PATH}/**
,例如http://localhost:8060/employee/**
。Swagger UI 在 address 下可用http://localhost:8060/swagger-ui.html
。在運行所有必需的 Spring Boot 應用程序之后,讓我們先來看看 Eureka。
訪問在網關上公開的 Swagger UI 后,您可能會看到我們可以在發現中注冊的所有三個微服務之間進行選擇。這正是我們想要實現的。
結論
Springdoc OpenAPI 兼容 OpenAPI 3,並支持 Spring WebFlux,而 SpringFox 不支持。因此,選擇似乎是顯而易見的,特別是如果您使用的是響應式 API 或 Spring Cloud Gateway。在本文中,我向您展示了如何在具有網關模式的微服務架構中使用 Springdoc。
使用 Zuul、Ribbon、Feign、Eureka 和 Sleuth、Zipkin 創建簡單spring cloud微服務用例-spring cloud 入門教程
微服務集成SPRING CLOUD SLEUTH、ELK 和 ZIPKIN 進行監控-spring cloud 入門教程
使用Hystrix 、Feign 和 Ribbon構建微服務-spring cloud 入門教程
使用 Spring Boot Admin 監控微服務-spring cloud 入門教程