本文主要用于介绍用户CICD流程与API网关整合的通用方法实践。该方法的核心是以swagger为桥接,通过API网关的ImportSwagger接口来完成您的API的自动创建和更新。
一、概述
API网关提供了完备的OpenAPI接口,用户可以通过这些接口完成API网关的管理需要。用户CICD集成API网关的核心,其实就是对API网关提供的管理接口进行封装整合。
如下图所示, 一个整合了API网关的通用CICD流程,主要有如下步骤:
步骤1:自动从您的API业务代码中获取swagger定义
步骤2:创建API分组
步骤3:通过API网关的OpenAPI导入API定义,并发布在不同的环境中
步骤4:对API进行各项额外配置
自动获取Swagger定义
用户开发时,可以自行整合一个API DOC框架(本文示例选择的是SpringFox)到自己的后端服务中。这些框架一般对原有代码都是无侵入的,所以接入相对方便。同时,API DOC框架随后端服务启动时,提供Swagger的获取接口。API网关通过访问这些接口,自动获取Swagger定义
创建API分组
用户可以在API网关控制台手动创建分组,或者通过CreateApiGroup - 创建API分组创建分组。用户创建分组后,可以进行绑定独立域名以及绑定证书等操作。
通过OpenAPI导入API并发布
用户通过集成API网关提供的ImportSwagger接口,并将Swagger获取接口获取的swagger数据作为参数,完成API的创建工作。在完成API在API网关的创建后,用户可以将其发布到所需的环境。完成API的发布后,用户即可访问对应的服务。
额外配置
为了更灵活的满足用户个性化管理需求,API网关提供了丰富的插件。包括:流量控制插件,IP访问控制插件,CORS插件以及JWT插件等。并根据需求选择配置相关的插件,来丰富该接口的鉴权及管控能力。
二、实现示例
本章节对提供的示例代码进行讲解说明,本文的示例代码仅提供了最基本的cicd场景,用户可根据实际情况进行调整和扩充。
2.1 示例代码
2.2 相关技术
本示例主要使用到的相关技术如下:
2.2.1 API网关相关链接
导入API网关的扩展Swagger定义介绍了如何配置可导入API网关的Swagger文件,API网关通过设计swagger支持的扩展内容,来完成标准swagger的直接导入和带有用户自定义配置的swagger导入。
ImportSwagger - 通过 Swagger 创建 API介绍了ImportSwagger接口。接口中主要参数为:
groupId: 用于存储用户swagger导入的API的分组ID。
data: 用户的swagger文件 。
globalCondition: 用于用户添加自定义的配置内容, 比如通过x-apigateway-backend-info标签,加入用户自定义后端的内容。
2.2.2 SpringFox
为了更直观的展示如何运用swagger便捷的将后端服务同步到API网关中,本文提供了一个使用SpringFox库的后端服务。 SpringFox是一个开源的API DOC的框架,它可以通过为服务Controller接口添加注释的方式,便捷的形成swagger,并在服务运行时,提供获取swagger的接口。
2.3 服务端自动生成swagger定义
服务端创建了一个基于springboot的极简Web服务,用于展示一般用户基于现有服务提供swagger的方法。
2.3.1 依赖库
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
2.3.2 SpringFox的配置
SpringFox是对用户原始服务相对友好的框架。用户无需对现有的接口和模型类进行任何修改,仅需要增加一个SpringFox的配置类,即可完成Springfox框架的接入工作。在服务启动后,该框架会自动解析springboot web框架中的注释,来自动生成swagger中所需的服务信息。同时,对于服务中引用的类进行解析,来生成swagger所需的模型信息。
SpringFox框架的配置项
本示例中,配置项进行了如下核心设置:
指出文档格式(Swagger2)
指出用于生成API DOC的包名
@Configuration
@EnableSwagger2
public class SpringFoxConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("com.example.swagger.controller"))
.paths(PathSelectors.any())
.build();
}
}
如何查看Swagger
启动服务后, 可以通过访问https://localhost:8080/swagger-ui.html
来打开swagger UI来进行swagger提供的功能,具体查看官网swagger.io
说明。
从截图中我们可以看到, 示例代码中的服务接口以及模型类均已被自动解析
如何获取Swagger
为了可以接入用户CICD的流程,获取swagger内容的接口是必不可少的。用户启动服务后,用户可以通过/v2/api-docs接口获取swagger内容。
2.4 创建API分组
用户可以通过以下方式创建分组
2.4.1 通过控制台创建
用户通过在API网关控制台-分组管理界面创建分组。完成分组创建后,可以进入分组详情页,查看对应的分组ID及其他相关信息。
2.4.2 通过OpenAPI创建API分组
通过API网关的openapi提供的CreateApiGroup - 创建API分组接口完成APIGroup的创建。同时,用户可以配合其他API完成用户独立域名以及绑定证书等其他操作。
2.5 ImportSwagger接口的使用
用户能否实现基于API网关的CICD流程,其核心关键是:
是否有接口可以获取swagger
标准swagger如何导入API网关
如2.2.2章节所介绍的内容. 我们已经可以获取描述后端服务所有接口和模型的swagger. 如何将标注的Swagger导入到API网关是我们本章节的重点.
2.5.1 基于API网关的Swagger扩展
API网关为了便于用户体验API网关的能力,支持将原生Swagger导入到API网关中。通过这种方式,API网关会自动创建基于Swagger的所有API,并且其默认后端为MOCK形式。
但是,用户真实的CICD场景往往需要的是API网关创建的API最终真正的访问到用户的后端服务。这样,就需要用户进行后端服务信息的配置。但是,这些信息原生的swagger是不具备的,所以,API网关提供了基于Swagger的扩展。
基于Swagger的扩展主要包括:后端服务配置,后端参数配置,认证方式等API网关所必须的或者特有的内容的配置。这些拓展支持全局配置。同时,也支持每个API中单独配置。 最终达到,用户原生swagger配合API网关swagger扩展,真正实现满足用户生产环境所需的API配置。
本文示例中,仅使用了x-apigateway-backend-info扩展来进行说明。示例中,用户的后端服务HTTP服务,我们假设其线上域名为www.aliyun.com。当然,后段地址也可以通过#环境变量#的形式进行配置。
我们在导入API网关的扩展Swagger定义一文中查看后端为HTTP类型的后端如何配置,其中type和address为必填项,后端path和method为空时,当前API的请求地址和HTTP方法,timeout默认为10000ms。
x-aliyun-apigateway-backend:
type: HTTP
address: 'http://www.aliyun.com'
path: '/builtin/echo'
method: get
timeout: 10000
2.5.2 通过ImportSwagger导入用户原生Swagger
ImportSwagger是用户原生Swagger导入到API网关的核心入口。这个接口有三个核心参数:
GroupId:用于指定存储swagger导入API的分组。
data:用于指定用户原生的Swagger。
globalCondition:用于传入用户的自定义配置,如通用后端服务地址。
Maven依赖
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.5.0</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-cloudapi</artifactId>
<version>4.9.3</version>
</dependency>
获取用户原生swagger
上文已经提及,用户在完成SpringFox框架引入和配置后,在服务启动时,就会自动生成/v2/api-docs接口用于获取描述后端服务的swagger。
private String getSwaggerData(){
HttpURLConnection connection = null;
...
...
String result = null;
try {
URL url = new URL(swaggerApiDocUrl);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();
...
...
} catch (Exception e) {
e.printStackTrace();
} finally {
...
...
connection.disconnect();
}
return result;
}
配置基于API网关的Swagger扩展
正确的配置Swagger扩展是用户通过导入Swagger创建满足其需求的API的核心环节. 这些基于API网关的swagger扩展可以通过ImportSwagger接口中的globalCondition参数传入. globalCondition的格式为Json String。
key: 基于swagger的API网关扩展的名称, 如:x-apigateway-backend-in
value: 对应swagger扩展的值。
示例代码中,通过配置API的通用后端地址,实现导入API网关的API可以访问到其真正的后端服务。
为了示例代码的整洁,我们根据2.5.1中HTTP类型的后端服务说明,创建SwaggerBackendInfoBase类,用于配置后端服务信息。
public class SwaggerBackendInfoBase {
private String type;
private String address;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
我们根据用户的后端服务信息,完成globalCondition参数的赋值。
// 配置API网关所需的服务后端信息
SwaggerBackendInfoBase info = new SwaggerBackendInfoBase();
info.setType("HTTP");
info.setAddress("http://www.aliyun.com");
// 将API的后端服务后端信息
Map<String, String> globalCondition = new HashMap<>();
globalCondition.put("x-aliyun-apigateway-backend", JSON.toJSONString(info));
ImportSwagger
上文中,我们已经完成了Group的创建,原生Swagger的获取以及GlobalCondition参数的创建。我们调用API网关openapi提供的ImportSwagger接口完成API的导入,并可以API网关控制台查看导入结果。
2.6 部署API
用户可以在API管理页面选择对应的分组,通过选择需要发布的API进行发布.用户通过发布使导入的API生效。
三、总结
自此, 如何将用户后端服务的API接口快速的同步到API网关已经完成。API网关致力于让用户专注于后端服务的开发, 将认证、流控等通用切面功能交给API网关处理,结合ImportSwagger接口的使用,完成后端服务与API网关的联动,大大减少了API网关的配置过程。同时,让API网关的配置和管理集成到用户的CICD流程中成为可能。