每一個服務都有本身的接口,經過Swagger來管理接口文檔。在服務較多的時候咱們但願有一個統一的入口來進行文檔的查看,這個時候能夠在Zuul中進行文檔的聚合顯示。
下面來看下具體的整合步驟以及採坑記錄。Cloud版本:Finchley.SR2, Boot版本:2.0.6
加入Swagger的依賴:
前端
1. <!-- Swagger --> 2. <dependency> 3. <groupId>io.springfox</groupId> 4. <artifactId>springfox-swagger-ui</artifactId> 5. <version>2.9.2</version> 6. </dependency> 7. <dependency> 8. <groupId>io.springfox</groupId> 9. <artifactId>springfox-swagger2</artifactId> 10. <version>2.9.2</version> 11. </dependency>
增長聚合代碼:spring
1. @EnableSwagger2 2. @Component 3. @Primary 4. public class DocumentationConfig implements SwaggerResourcesProvider { 5. 6. @Autowired 7. private DiscoveryClient discoveryClient; 8. 9. @Value("${spring.application.name}") 10. private String applicationName; 11. 12. @Override 13. public List<SwaggerResource> get() { 14. List<SwaggerResource> resources = new ArrayList<>(); 15. // 排除自身,將其餘的服務添加進去 16. discoveryClient.getServices().stream().filter(s -> !s.equals(applicationName)).forEach(name -> { 17. resources.add(swaggerResource(name, "/" + name + "/v2/api-docs", "2.0")); 18. }); 19. return resources; 20. } 21. 22. private SwaggerResource swaggerResource(String name, String location, String version) { 23. SwaggerResource swaggerResource = new SwaggerResource(); 24. swaggerResource.setName(name); 25. swaggerResource.setLocation(location); 26. swaggerResource.setSwaggerVersion(version); 27. return swaggerResource; 28. } 29. 30. }
我這邊直接用DiscoveryClient 獲取服務列表進行聚合,固然你也能夠固定寫上你的服務列表,或者對接配置中心均可以。
其實除了DiscoveryClient 獲取服務列表,咱們也能夠根據Zuul中路由的配置來獲取,能夠使用RouteLocator 來操做。方式不少,用哪一種均可以。
正常狀況下上面的整合步驟沒任何問題,今天有朋友在星球提問,說本身的業務服務加了context-path,Zuul中聚合的Swagger文檔沒法顯示,由於路徑錯了,少了配置的context-path。效果以下圖:
也就是說在進行資源添加的時候須要將context-path加進去,也就是須要改動下面的代碼:
後端
1. resources.add(swaggerResource(name, "/" + name + "/v2/api-docs", "2.0"));
api
最簡單的就是加一個配置,配置好每一個服務對應的context-path,這樣在這裏直接拼接上去就完事了。但這樣顯得有點低端呀,哈哈。
DiscoveryClient 是很強大的,咱們能夠用DiscoveryClient 來獲取Eureka中的信息,此時我有了一個想法,那就是業務服務將自身的context-path放入Eureka的metadata-map中,而後Zuul中聚合的時候從metadata-map中獲取context-path就好了。
業務服務加配置:
緩存
1. server.servlet.context-path=/yinjihuan 2. eureka.instance.metadata-map.context-path=${server.servlet.context-path}
Zuul中改造:併發
1. @Override 2. public List<SwaggerResource> get() { 3. List<SwaggerResource> resources = new ArrayList<>(); 4. // 排除自身,將其餘的服務添加進去 5. discoveryClient.getServices().stream().filter(s -> !s.equals(applicationName)).forEach(name -> { 6. Optional<ServiceInstance> instanceOptional = discoveryClient.getInstances(name).stream().findFirst(); 7. if (instanceOptional.isPresent() && instanceOptional.get().getMetadata().containsKey("context-path")) { 8. String contexPath = instanceOptional.get().getMetadata().get("context-path"); 9. resources.add(swaggerResource(name, "/" + name + contexPath + "/v2/api-docs", "2.0")); 10. } else { 11. resources.add(swaggerResource(name, "/" + name + "/v2/api-docs", "2.0")); 12. } 13. 14. }); 15. return resources; 16. }
這樣就完美解決了增長context-path致使的問題,加入星球咱們一塊兒學習吧。app
星球正在搞活動,詳情請查看:優秀程序猿背後的故事框架
加入星球特權分佈式
一、從前端到後端玩轉Spring Cloud
二、實戰分庫分表中間件Sharding-JDBC
三、實戰分佈式任務調度框架Elastic Job
四、配置中心Apollo實戰
五、高併發解決方案之緩存
六、更多課程等你來解鎖,20+課程
ide
尹吉歡我不差錢啊喜歡做者