著者:macrozheng
元のリンク:https://mp.weixin.qq.com/s/4LK0Hs15nHlSOzXG4h149w
私のmall-swarmマイクロサービスプロジェクトには、APIドキュメントの集約がないことに注意してください。各サービスのAPIドキュメントにアクセスするには、個別のswagger-ui.htmlページにアクセスする必要があります。マイクロサービスを使用するため、統一されたAPIドキュメントが必要です。入り口、私は最近、knife4jがこの領域をサポートしていることを発見しました。この記事では、その実装について詳しく紹介します。皆さんのお役に立てれば幸いです。
事前知識
Nacosを登録センターとして使用し、Gatewayをゲートウェイとして使用し、knife4jを使用してAPIドキュメントを生成します
アプリケーションのアーキテクチャ
理想的なソリューションは次のようになります。ゲートウェイはAPIドキュメントの統合エントリポイントとして機能します。ゲートウェイはすべてのマイクロサービスのドキュメントを集約し、ゲートウェイで切り替えることにより他のサービスAPIドキュメントへのアクセスを実現します。
関連サービス部門:
- micro-knife4j-gateway:ゲートウェイサービスは、マイクロサービスAPIドキュメントのアクセスエントリとして、すべてのAPIドキュメントを集約し、ドキュメントのフロントエンドUIパッケージを導入する必要があります。
- micro-knife4j-user:ユーザーサービス、共通APIサービス。ドキュメントのフロントエンドUIパッケージを導入する必要はありません。
- micro-knife4j-order:注文サービス、共通APIサービス、ドキュメントのフロントエンドUIパッケージを導入する必要はありません。
実装
以下は、Spring Cloud Gateway + knife4j集約APIドキュメントの実装の詳細な紹介であり、ユーザーサービス、注文サービス、ゲートウェイサービスを順に構築します。
micro-knife4j-user
まず、共通のAPIサービスであるユーザーサービスを構築しましょう。これは非常に単純で、knife4jを統合するのに必要な手順は3つだけです。
- pom.xmlに関連する依存関係、SpringBoot Web関数の依存関係、knife4jマイクロサービスの依存関係(APIドキュメントを含まないフロントエンドUIパッケージ)を追加します。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
</dependency>
</dependencies>
- application.ymlに関連する構成を追加し、Nacosレジストリーを構成します。
server:
port: 9501
spring:
profiles:
active: dev
application:
name: micro-knife4j-user
cloud:
nacos:
discovery:
server-addr: localhost:8848
management:
endpoints:
web:
exposure:
include: "*"
- Swagger関連の構成、非常に従来の構成を追加し、@ EnableKnife4jアノテーションを追加して、knife4jの拡張機能を有効にします。
/**
* Swagger API相关配置
*/
@Configuration
@EnableSwagger2
@EnableKnife4j
public class Swagger2Config {
@Bean
public Docket createRestApi(){ return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.macro.cloud.controller"))
.paths(PathSelectors.any())
.build();
} private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("micro-knife4j-user")
.description("用户服务API文档")
.contact("macro")
.version("1.0")
.build();
}}
マイクロナイフ4j注文
次に、一般的なAPIサービスである注文サービスを作成します。上記のユーザーサービスの設定を参照してください。
マイクロナイフ4J-ゲートウェイ
最後に、マイクロサービスAPIドキュメントの統合エントリポイントとして機能し、すべてのマイクロサービスAPIドキュメントを集約するゲートウェイサービスを構築します。
- pom.xmlに関連する依存関係、ゲートウェイに関連する依存関係、knife4j Starter(APIドキュメントを含むフロントエンドUIパッケージ)を追加します。
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
</dependencies>
- application.ymlに関連する構成を追加し、Nacosレジストリ、ユーザーサービス、注文サービスのルートを構成します。
server:
port: 9201
spring:
profiles:
active: dev
application:
name: micro-knife4j-gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
routes: #配置路由路径
- id: user-service
uri: lb://micro-knife4j-user
predicates:
- Path=/user-service/**
filters:
- StripPrefix=1
- id: order-service
uri: lb://micro-knife4j-order
predicates:
- Path=/order-service/**
filters:
- StripPrefix=1
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能
lower-case-service-id: true #使用小写服务名,默认是大写
- Swaggerリソース構成をゲートウェイに追加して、他のマイクロサービスのSwaggerのapi-docsアクセスパスを集約します。
/**
* Swagger资源配置
* Created by macro on 2020/7/9.
*/
@Slf4j
@Component
@Primary
@AllArgsConstructor
public class SwaggerResourceConfig implements SwaggerResourcesProvider {
private final RouteLocator routeLocator;
private final GatewayProperties gatewayProperties;
@Override
public List<SwaggerResource> get() {
List<SwaggerResource> resources = new ArrayList<>();
List<String> routes = new ArrayList<>();
//获取所有路由的ID
routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
//过滤出配置文件中定义的路由->过滤出Path Route Predicate->根据路径拼接成api-docs路径->生成SwaggerResource
gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId())).forEach(route -> {
route.getPredicates().stream()
.filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
.forEach(predicateDefinition -> resources.add(swaggerResource(route.getId(),
predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
.replace("**", "v2/api-docs"))));
});
return resources;
}
private SwaggerResource swaggerResource(String name, String location) {
log.info("name:{},location:{}", name, location);
SwaggerResource swaggerResource = new SwaggerResource();
swaggerResource.setName(name);
swaggerResource.setLocation(location);
swaggerResource.setSwaggerVersion("2.0");
return swaggerResource;
}
}
- Swaggerのapi-docsのアクセスパスは何ですか?このパスはJSON形式のデータを返し、SwaggerレンダリングAPIドキュメントページのすべてのデータはこれから取得されます。たとえば、ユーザーサービスは次の情報、アクセスアドレスを返します:http:// localhost:9201 / user-service / v2 / api- docs
- 次に、Swaggerの各構成のノードをカスタマイズする必要があります。これは、Swagger内でデータを取得するためのインターフェースをカスタマイズするだけです。
/**
* 自定义Swagger的各个配置节点
* Created by macro on 2020/7/9.
*/
@RestController
public class SwaggerHandler {
@Autowired(required = false)
private SecurityConfiguration securityConfiguration;
@Autowired(required = false)
private UiConfiguration uiConfiguration;
private final SwaggerResourcesProvider swaggerResources;
@Autowired
public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
this.swaggerResources = swaggerResources;
} /**
* Swagger安全配置,支持oauth和apiKey设置
*/
@GetMapping("/swagger-resources/configuration/security")
public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK)); } /**
* Swagger UI配置
*/
@GetMapping("/swagger-resources/configuration/ui")
public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
return Mono.just(new ResponseEntity<>(
Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK)); } /**
* Swagger资源配置,微服务中这各个服务的api-docs信息
*/
@GetMapping("/swagger-resources")
public Mono<ResponseEntity> swaggerResources() {
return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
}}
- たとえば、swagger-resourcesインターフェースを使用して、すべてのマイクロサービスのapi-docsアクセスパスを取得できます。アクセス情報は次のとおりです。アクセスアドレス:http:// localhost:9201 / swagger-resources
デモ
次に、マイクロサービスAPIドキュメント集約の機能を示します。ゲートウェイのAPIドキュメントページにアクセスするだけで、関連するサービスのAPIドキュメントに自分で切り替えることができます。
- その前に、まずNacosレジストリを開始し、次にmicro-knife4j-user、micro-knife4j-order、micro-knife4j-gatewayサービスを順に開始します。
- ゲートウェイからAPIドキュメントにアクセスします。アクセスアドレス:http:// localhost:9201 / doc.html
- 左上隅のスイッチコンポーネントを介して、対応するサービスのAPIドキュメントに切り替えることができます。
- APIドキュメントを見ると、すべてのインターフェイスが対応するアクセスプレフィックスで追加されており、通常どおりアクセスできることがわかります。
Swagger UIに切り替えます
knife4jインターフェースを使用したくないが、元のSwaggerインターフェースを使用したい場合もサポートされています切り替え方法は非常に簡単なので、以下で説明します。
- 最初に、pom.xml内のknife4jの関連する依存関係、主に次の2つの依存関係を削除する必要があります。
<dependencies>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
</dependency>
</dependencies>
- Swagger関連の依存関係をpom.xmlに追加し、元の@ EnableKnife4jアノテーションを削除します。
<dependencies>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.0</version>
</dependency>
</dependencies>
- すべてのサービスを再起動し、ゲートウェイのAPIドキュメントパスにアクセスして表示します。http:// localhost:9201 / swagger-ui.html
総括する
knife4jとネイティブSwaggerの間のマイクロサービスの使用を比較すると、knife4jがspringfox-swaggerの拡張されたUI実装であり、完全にspringfox-swaggerの使用方法に従うことが証明されます。
参照
公式ドキュメント:https://doc.xiaominfo.com/guide/ui-front-gateway.html
プロジェクトのソースアドレス
https://github.com/macrozheng/springcloud-learning/tree/master/micro-knife4j