构建spring cloud 文档模块

spring cloud作为微服务的解决方案,有gateway这种网关,自然也要有opendoc这种统一的文档测试模块,可惜并没有,但是我们可以自己基于spring gateway自己构建一个,下面介绍下风铃的opendoc的构建方案
1.需求
前后端分离,前端需要后端的文档辅助自己的开发,同时后端也不想花费过多的时间再这个上面
2.方案
百度许久感觉还是swagger方案最简单,普及率高,使用方便,符合现代风格,ui和服务分离也容易改造,也找到了一个自定义ui的方案
swagger-bootstrap-ui,这样我们的方案就出来了
基于spring gateway做请求转发的代理,基于swagger做后台的文档生产,基于swagger-bootstrap-ui做前段UI,因为风格和风铃不匹配打算自己改
3.实现
每个服务都集成swgger,用于文档生成和自己测试

<dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
        </dependency>

然后opendoc配置和gateway一样都集成spring gateway和nacos用于访问服务和读取文档

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>

这样我们opendoc功能和gateway一致,也可以通过后缀,做到跨域访问后缀
下一步就是查看一下,swagger-bootstrap-ui的逻辑,然后我们替换成自己的代码模拟swagger 的请求(其实就是透传,组合)
swagger主要有连个请求一个是获取所有的service,就是所有的后台请求组:

@Bean
    public Docket createSystemRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .groupName("基础管理")
                .select()
                .apis(RequestHandlerSelectors.basePackage("cn.afterturn.boot.admin"))
                .paths(PathSelectors.any())
                .build()
                .globalResponseMessage(RequestMethod.GET, getResponseMessages())
                .globalResponseMessage(RequestMethod.POST, getResponseMessages())
                .globalResponseMessage(RequestMethod.PUT, getResponseMessages())
                .globalResponseMessage(RequestMethod.DELETE, getResponseMessages());
    }

随便说下,因为spring cloud的FeignClient 实际上也是controller 并且注解基本上也是一样的,所以我们最好是扫码包,不要直接扫描@ApiOperation注解,会把依赖加进来也就是重复的数据

模拟service
去掉gateway和opendoc两个自己注册的服务,没有接口提供
把所有注册服务的group都统计到一起,返回给前端

@GetMapping("/services")
    public List<SwaggerProjectModel> serviceUrl() {
        List<ServiceInstance>     serviceInstanceList = getServiceInstanceList();
        List<SwaggerProjectModel> services            = new ArrayList<>();
        SwaggerProjectModel       model;
        for (int i = 0; i < serviceInstanceList.size(); i++) {
            try {
                if (serviceInstanceList.get(i).getServiceId().equalsIgnoreCase("lemur-gateway")
                        || serviceInstanceList.get(i).getServiceId().equalsIgnoreCase("lemur-opendoc")) {
                    continue;
                }
                log.debug("start get third services success");
                List<SwaggerProjectModel> tempList = JSON.parseArray(HttpUtil.get(serviceInstanceList.get(i).getUri().toString() + "/swagger-resources", 60 * 1000), SwaggerProjectModel.class);
                log.debug("end   get third services success");
                for (int j = 0; j < tempList.size(); j++) {
                    model = tempList.get(j);
                    model.setName(serviceInstanceList.get(i).getServiceId() + ":" + model.getName());
                    model.setUrl("/doc/group/" + serviceInstanceList.get(i).getServiceId() + "/" + getGroup(model.getUrl()));
                    model.setPrefix(prefixMap.get(getRealServiceName(serviceInstanceList.get(i).getServiceId())));
                    model.setBasePath(prefixMap.get(getRealServiceName(serviceInstanceList.get(i).getServiceId())));
                    services.add(model);
                }

            } catch (Exception e) {
            }
        }
        log.debug("get services success");
        return services;
    }

前端要的就是这个列表,其中basePath就是我们gateway转发的地址,方便gateway转发

    private String location;
    private String name;
    private String swaggerVersion;
    private String url;
    private String basePath;

然后前端就获取的所有的group,下一步就是根据group获取下面所有的函数的,也很简单,把服务透传到下面去就可以了

@GetMapping("/group/{serviceId}/{group}")
    public String group(@PathVariable String serviceId, @PathVariable String group) {
        if (group.equalsIgnoreCase("dubbo")) {
            return HttpUtil.get(discoveryClient.getInstances(serviceId).get(0).getUri().toString() + "/swagger-dubbo/api-docs");
        }
        return HttpUtil.get(discoveryClient.getInstances(serviceId).get(0).getUri().toString() + "/v2/api-docs?group=" + HttpUtil.encodeUtf8(group));
    }

最终效果,可以自己切换服务在这里插入图片描述
到这里基本就完成了,前端小伙伴也不用每个都去问一遍了,也可以测试,后端更新还及时,有兴趣的小伙伴可以去看看源码
https://gitee.com/lemur/windbell

风铃平台是新一代面向新移动化的基础开发平台,专门为开发者提供面向钉钉,企业微信,自己构建小程序,自己构建app以及开发平台的基础平台 无论是个人、团队、或是企业,都能够用风铃快速开发上线。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值