有很多讀者問過這樣的一個問題:
雖然使用Swagger可以為Spring MVC編寫的接口生成了API文檔,但是在微服務化之後,這些API文檔都離散在各個微服務中,是否有辦法將這些接口都整合到一個文檔中?
之前給大家的回覆都只是簡單的說了個思路,昨天正好又有人問起,索性就舉個例子寫成博文供大家參考吧。
如果你還不了解 SpringCloudZuul和 Swagger,建議優先閱讀下面兩篇,有一個初步的了解:
1、準備工作上面說了問題的場景是在微服務化之後,所以我們需要先構建兩個簡單的基於Spring Cloud的微服務,命名為 swagger-service-a和 swagger-service-b。
下面只詳細描述一個服務的構建內容,另外一個只是名稱不同,如有疑問可以在文末查看詳細的代碼樣例。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
@EnableSwagger2Doc
@EnableDiscoveryClient
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
@RestController
class AaaController {
@Autowired
DiscoveryClient discoveryClient;
@GetMapping("/service-a")
public String dc() {
String services = "Services: " + discoveryClient.getServices();
System.out.println(services);
return services;
}
}
}
其中, @EnableSwagger2Doc註解是我們自製Swagger Starter中提供的自定義註解,通過該註解會初始化默認的Swagger文檔設置。下面還創建了一個通過Spring MVC編寫的HTTP接口,用來後續在文檔中查看使用。
spring.application.name=swagger-service-a
server.port=10010
eureka.client.serviceUrl.defaultZone=http://eureka.didispace.com/eureka/
swagger.base-package=com.didispace
其中,eureka服務端的配置採用了本站的公益eureka,大家可以通過http://eureka.didispace.com/查看詳細以及使用方法。另外, swagger.base-package參數制定了要生成文檔的package,只有 com.didispace包下的Controller才會被生成文檔。
注意:上面構建了swagger-service-a服務,swagger-service-b服務可以如法炮製,不再贅述。
2、構建API網關並整合Swagger在Spring Cloud構建微服務架構:服務網關(基礎)一文中,已經非常詳細的介紹過使用Spring Cloud Zuul構建網關的詳細步驟,這裡主要介紹在基礎網關之後,如何整合Swagger來匯總這些API文檔。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
@EnableSwagger2Doc
@EnableZuulProxy
@SpringCloudApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
@Component
@Primary
class DocumentationConfig implements SwaggerResourcesProvider {
@Override
public List<SwaggerResource> get() {
List resources = new ArrayList<>();
resources.add(swaggerResource("service-a", "/swagger-service-a/v2/api-docs", "2.0"));
resources.add(swaggerResource("service-b", "/swagger-service-b/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;
}
}
}
說明: @EnableSwagger2Doc上面說過是開啟Swagger功能的註解。這裡的核心是下面對 SwaggerResourcesProvider的接口實現部分,通過 SwaggerResource添加了多個文檔來源,按上面的配置,網關上Swagger會通過訪問 /swagger-service-a/v2/api-docs和 swagger-service-b/v2/api-docs來加載兩個文檔內容,同時由於當前應用是Zuul構建的API網關,這兩個請求會被轉發到 swagger-service-a和 swagger-service-b服務上的 /v2/api-docs接口獲得到Swagger的JSON文檔,從而實現匯總加載內容。
3、測試驗證將上面構建的兩個微服務以及API網關都啟動起來之後,訪問網關的swagger頁面,比如: http://localhost:11000/swagger-ui.html,此時可以看到如下圖所示的內容:
可以看到在分組選擇中就是當前配置的兩個服務的選項,選擇對應的服務名之後就會展示該服務的API文檔內容。
5、代碼示例本文示例讀者可以通過查看下面倉庫的中的 swagger-service-a、 swagger-service-b、 swagger-api-gateway三個項目:
Github:
https://github.com/dyc87112/SpringCloud-Learning/tree/master/2-Dalston%E7%89%88%E6%95%99%E7%A8%8B%E7%A4%BA%E4%BE%8B/
Gitee:
https://gitee.com/didispace/SpringCloud-Learning/tree/master/2-Dalston%E7%89%88%E6%95%99%E7%A8%8B%E7%A4%BA%E4%BE%8B
除了本文的方法之外,我還開發了一個開源項目,您也可以直接來使用,歡迎Star支持:https://github.com/dyc87112/swagger-butler
最後再給大家推薦一個《零基礎學Python》的視頻課程。
Python這門編程,我是非常推薦大家要去掌握的,由於該課程屬於基礎類課程,所以一些非計算機專業的朋友也可以去嘗試學習和應用。因為它比起Java來說它更容易上手,通過一些基礎知識內容就可以幫助減輕一些日常工作繁瑣的事情,讓你能夠事半功倍。加上現在爬蟲、AI等框架的發展,如果你有足夠的積極性和想像空間,可以玩的內容會越來越多,所以我把這個專欄推薦給你,希望你可以喜歡並有所收穫!
……
……可關注我的公眾號
深入交流、更多福利
掃碼加入我的知識星球
點擊「閱讀原文」,看本號其他精彩內容