Solon Cloud+Gateway整合Knife4j文档聚合

247 阅读1分钟

Solon版本在2.9.0-M3支持服务注册发现动态聚合文档

1.父级工程依赖引入

<parent>
    <groupId>org.noear</groupId>
    <artifactId>solon-parent</artifactId>
    <version>2.9.0-M3</version>
    <relativePath />
</parent>

2.创建网关gateway或者doc服务

我这边是将接口文档聚合到gateway中,如果你没有gateway,那个可以单独创建一个文档聚合的服务比如就叫doc-service,如果你也需要创建一个Solon Cloud Gateway,那么你可以看juejin.cn/post/739834…

2.1、gateway/pom.xml引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>superb-solon</artifactId>
        <groupId>com.superb</groupId>
        <version>1.0.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>
    <artifactId>superb-gateway</artifactId>
    <description>Superb 网关(微服务聚合)</description>
    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- nacos注册中心 -->
        <dependency>
            <groupId>org.noear</groupId>
            <artifactId>nacos2-solon-cloud-plugin</artifactId>
        </dependency>
        <!-- 文档聚合依赖 -->
        <dependency>
            <groupId>org.noear</groupId>
            <artifactId>solon-openapi2-knife4j</artifactId>
        </dependency>
    </dependencies>

    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.noear</groupId>
                <artifactId>solon-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.2、聚合配置

引入依赖后不用在代码里做操作,只需在yml中配置即可,我这边使用的nacos作为配置中心,写在了nacos中,当然你也可以直接写到app.yml中,具体配置为

solon:
    # 网关聚合接口文档配置
    docs:
        discover:
        #目标服务的文档接口路径模式(要么带变量 {service},要么用统一固定值)
        # 注:这里的default是其他服务配置时的bean名称!!!
        uriPattern: "swagger/v2?group=default"
        #同步目标服务上下线状态(如果下线,则文档不显示)
        syncStatus: true
        # 排除不需要聚合的服务,服务名称
        excluded:
            - superb-gateway
        # 在聚合中Solon适配了多个注册中心在Solon Cloud Config篇https://solon.noear.org/article/family-solon-cloud-config
        # 目前只有nacos支持拉取所有的服务接口,为了适配所有的注册中心,Solon使用了LoadBalance.get(name)获取服务,也就是在聚合中,需要你的服务被访问过,才能被聚合
        # 当然Solon也有对应的解决办法即included属性,可以主动调用LoadBalance.get(name)去聚合
        included:
            - superb-system-biz
            - superb-allocation-biz

3、子服务

3.1、引入依赖

<!-- 接口文档knife4j-solon依赖 -->
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>solon-openapi2-knife4j</artifactId>
</dependency>

3.2、在子服务中配置

3.2.1、自定义拓展配置

import lombok.Data;

/**
 * @Author: ajie
 * @CreateTime: 2024-07-25 16:06
 */
@Data
public class Knife4jProperties {

    /**
     * 服务网文档分组名称
     */
    private String groupName;

    /**
     * 文档标题
     */
    private String title = "superb接口文档";

    /**
     * 文档描述
     */
    private String description = "superb接口描述";

    /**
     * 版本
     */
    private String version = "v1.0";

    /**
     * 作者
     */
    private String author = "ajie";

    /**
     * 联系邮箱地址
     */
    private String email = "ajie-superb@163.com";
}

3.2.2、配置类

package com.superb.common.doc.config;

import com.github.xiaoymin.knife4j.solon.extension.OpenApiExtensionResolver;
import com.superb.common.doc.config.properties.Knife4jProperties;
import com.superb.common.utils.HeadersUtils;
import io.swagger.models.Scheme;
import io.swagger.models.parameters.HeaderParameter;
import org.noear.solon.annotation.Bean;
import org.noear.solon.annotation.Configuration;
import org.noear.solon.annotation.Inject;
import org.noear.solon.docs.DocDocket;
import org.noear.solon.docs.models.ApiContact;
import org.noear.solon.docs.models.ApiInfo;
import org.noear.solon.docs.models.ApiResource;

/**
 * 整合knife4j接口文档
 * https://solon.noear.org/article/568
 * @Author: ajie
 * @CreateTime: 2024-07-25 16:05
 */
@Configuration
public class Knife4jConfig {

    /**
     * 获取knife4j配置
     */
    @Inject
    private OpenApiExtensionResolver openApiExtensionResolver;

    /**
     * 自定义knife4j配置
     */
    @Inject("${knife4j.custom}")
    private Knife4jProperties properties;

    /**
     * 丰富点的
     * 注:bean name不能少了!!! 一定要有,且聚合中每个服务的bean name得一样才能正常聚合
     */
    @Bean("default")
    public DocDocket adminApi() {
        return new DocDocket()
                .groupName(properties.getGroupName())
                .vendorExtensions(openApiExtensionResolver.buildExtensions())
                .info(new ApiInfo().title(properties.getTitle())
                        .description(properties.getDescription())
                        .contact(new ApiContact().name(properties.getAuthor())
                                .email(properties.getEmail()))
                        .version(properties.getVersion()))
                .schemes(Scheme.HTTP.toValue(), Scheme.HTTPS.toValue())
                // 接口文档请求头 name为请求header字段,description接口文档中的描述,required是否为必填项
                .globalParams(new HeaderParameter().name("token").description("登录凭证").required(false))
                .apis(new ApiResource()); //所有存在Mapping+Swagger注解的方法
    }

}

3.聚合效果

访问网关或doc-service http://ip:port/doc.html

如果存在鉴权记得将接口文档资源过滤

/favicon.ico、/webjars/js/、/webjars/css/、/doc.html、/swagger-resources、/swagger/**

我这边的网关会转发到对应的服务,接口文档聚合的服务也需要转发,注意配置!!!

image.png