前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Zuul中聚合Swagger的坑

Zuul中聚合Swagger的坑

作者头像
猿天地
发布2019-05-13 19:44:24
1.3K0
发布2019-05-13 19:44:24
举报
文章被收录于专栏:猿天地

每个服务都有自己的接口,通过Swagger来管理接口文档。在服务较多的时候我们希望有一个统一的入口来进行文档的查看,这个时候可以在Zuul中进行文档的聚合显示。

下面来看下具体的整合步骤以及采坑记录。Cloud版本:Finchley.SR2, Boot版本:2.0.6

加入Swagger的依赖:

代码语言:javascript
复制
<!-- Swagger --><dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-swagger-ui</artifactId>    <version>2.9.2</version></dependency><dependency>    <groupId>io.springfox</groupId>    <artifactId>springfox-swagger2</artifactId>    <version>2.9.2</version></dependency>

增加聚合代码:

代码语言:javascript
复制
@EnableSwagger2@Component@Primarypublic class DocumentationConfig implements SwaggerResourcesProvider {
    @Autowired    private DiscoveryClient discoveryClient;
    @Value("${spring.application.name}")    private String applicationName;
    @Override    public List<SwaggerResource> get() {        List<SwaggerResource> resources = new ArrayList<>();        // 排除自身,将其他的服务添加进去        discoveryClient.getServices().stream().filter(s -> !s.equals(applicationName)).forEach(name -> {            resources.add(swaggerResource(name, "/" + name + "/v2/api-docs", "2.0"));        });        return resources;    }
    private SwaggerResource swaggerResource(String name, String location, String version) {        SwaggerResource swaggerResource = new SwaggerResource();        swaggerResource.setName(name);        swaggerResource.setLocation(location);        swaggerResource.setSwaggerVersion(version);        return swaggerResource;    }
}

我这边直接用DiscoveryClient 获取服务列表进行聚合,当然你也可以固定写上你的服务列表,或者对接配置中心都可以。

其实除了DiscoveryClient 获取服务列表,我们也可以根据Zuul中路由的配置来获取,可以使用RouteLocator 来操作。方式很多,用哪种都可以。

正常情况下上面的整合步骤没任何问题,今天有朋友在星球提问,说自己的业务服务加了context-path,Zuul中聚合的Swagger文档无法显示,因为路径错了,少了配置的context-path。效果如下图:

也就是说在进行资源添加的时候需要将context-path加进去,也就是需要改动下面的代码:

代码语言:javascript
复制
resources.add(swaggerResource(name, "/" + name + "/v2/api-docs", "2.0"));

最简单的就是加一个配置,配置好每个服务对应的context-path,这样在这里直接拼接上去就完事了。但这样显得有点低端呀,哈哈。

DiscoveryClient 是很强大的,我们可以用DiscoveryClient 来获取Eureka中的信息,此时我有了一个想法,那就是业务服务将自身的context-path放入Eureka的metadata-map中,然后Zuul中聚合的时候从metadata-map中获取context-path就行了。

业务服务加配置:

代码语言:javascript
复制
server.servlet.context-path=/yinjihuaneureka.instance.metadata-map.context-path=${server.servlet.context-path}

Zuul中改造:

代码语言:javascript
复制
@Overridepublic List<SwaggerResource> get() {    List<SwaggerResource> resources = new ArrayList<>();    // 排除自身,将其他的服务添加进去    discoveryClient.getServices().stream().filter(s -> !s.equals(applicationName)).forEach(name -> {        Optional<ServiceInstance> instanceOptional = discoveryClient.getInstances(name).stream().findFirst();        if (instanceOptional.isPresent() && instanceOptional.get().getMetadata().containsKey("context-path")) {            String contexPath = instanceOptional.get().getMetadata().get("context-path");            resources.add(swaggerResource(name, "/" + name + contexPath + "/v2/api-docs", "2.0"));        } else {            resources.add(swaggerResource(name, "/" + name + "/v2/api-docs", "2.0"));        }
    });    return resources;}

这样就完美解决了增加context-path导致的问题

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 猿天地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
微服务引擎 TSE
微服务引擎(Tencent Cloud Service Engine)提供开箱即用的云上全场景微服务解决方案。支持开源增强的云原生注册配置中心(Zookeeper、Nacos 和 Apollo),北极星网格(腾讯自研并开源的 PolarisMesh)、云原生 API 网关(Kong)以及微服务应用托管的弹性微服务平台。微服务引擎完全兼容开源版本的使用方式,在功能、可用性和可运维性等多个方面进行增强。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档