源宝导读:随着企业信息化进程的逐步深入,互联网技术的发展和分布式系统应用的日益广泛,直接导致大量异构系统的存在,这些系统往往各自独立、封闭运行,相互之间不存在或很少存在数据的交互,由于这种应用分割,多个系统之间往往存在数据的冗余以及功能的重叠,各个系统之间信息传输、资源利用困难,形成所谓的“信息孤岛”。天际·集成开放平台,提供轻量化的API、事件、消息、数据集成能力,可以帮助您积木式、配置化的构建高可靠、高性能、低延迟的应用集成解决方案,实现企业云上云下、不同厂商、不同架构、不同协议的应用互联互通,并且平台还提供可视化的运维管理、实时的运行监控,保障集成可持续健康运行。当前文章主要阐述集成平台连接中心的API管理能力,把不同协议、不同厂商的服务转化成统一标准的Http协议服务,对外提供操作能力。对Http协议的描述,采用国际标准OAS 3.0规范。
一、OAS 3.0 初识
介绍
OAS 3.0即:OpenAPI Specification 3.0.*;OpenAPI 规范 为 REST API 定义了一种标准的、与编程语言无关的接口描述,它允许人类和计算机发现和理解服务的功能,而无需访问源代码、附加文档或检查网络流量. 当通过 OpenAPI 正确定义时,消费者可以使用最少的实现逻辑理解远程服务并与之交互。与接口描述为低级编程所做的类似,OpenAPI 规范消除了调用服务时的猜测。
发展史(来源wiki:https://en.wikipedia.org/wiki/OpenAPI_Specification)
Swagger开发始于 2010 年初,由在在线词典公司Wordnik工作的 Tony Tam 开始。[3] 2015 年 3 月,SmartBear Software从 Wordnik 的母公司 Reverb Technologies 那里收购了开源 Swagger API 规范。[4]
2015 年 11 月,SmartBear 宣布将在Linux 基金会的赞助下创建一个名为 OpenAPI Initiative 的新组织。其他创始成员公司包括3scale、Apigee、CapitalOne、谷歌、IBM、Intuit、微软、PayPal和 Restlet。[5] [6] [7] SmartBear 向新组捐赠了 Swagger 规范。该小组也在考虑RAML和API Blueprint。[8] [9]
2016 年 1 月 1 日,Swagger 规范更名为 OpenAPI 规范 (OAS),并移至新的GitHub 存储库。[10]
2016 年 9 月,API World 大会向 SmartBear 颁发了 API 基础设施奖,以表彰其在 Swagger 上的持续工作。[11]
2017 年 7 月,OpenAPI Initiative 发布了其规范的 3.0.0 版。[12] MuleSoft是替代RESTful API 建模语言(RAML)的主要贡献者,加入了 OAS 并开源了他们的 API 建模框架工具,该工具可以从 RAML 输入生成 OAS 文档。
变更版本
2.0 & 3.0 根节点属性示意图
参考:https://swagger.io/blog/news/whats-new-in-openapi-3-0
节点说明 (参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#oasDocument)
OpenAPI 根对象
# OpenAPI 规范版本号
openapi: 3.0.0# API 元数据信息
info:# 服务器连接信息
servers:# API 的分组标签
tags: # 对所提供的 API 有效的路径和操作
paths:# 一个包含多种纲要的元素,可重复使用组件
components:# 声明 API 使用的安全机制
security:# 附加文档
externalDocs:
Info 对象
# API 元数据信息
info:title: xx开放平台接口文档 # 应用的名称description: | 简短的描述信息,支持 markdown 语法。| 表示换行,< 表示忽略换行。version: "1.0.0" # API 文档的版本信息termsOfService: 'http://swagger.io/terms/' # 指向服务条款的 URL 地址contact: # 所开放的 API 的联系人信息name: API Support # 人或组织的名称url: http://www.example.com/support # 指向联系人信息的 URL 地址email: apiteam@swagger.io # 人或组织的 email 地址license: # 所开放的 API 的证书信息。name: Apache 2.0url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#infoObject
Server 对象
所有的 API 端点都是相对于基本 URL 的。例如,假设 https://api.example.com/v1 的基本 URL 中,/users 端点指的是 https://api.example.com/v1/users。
https://api.example.com/v1/users?role=admin&status=active
\ __________________ / \__/ \ ______________________ /服务器URL 端点路径 查询参数
Server 表示一个服务器的对象。这里通常填写测试服务器或者生产服务器的 IP 地址、端口版本号等信息(指定基本 URL)。
# 服务器连接信息
servers:- url: https://development.gigantic-server.com/v1description: 开发服务器- url: https://staging.gigantic-server.com/v1description: 测试服务器- url: https://api.gigantic-server.com/v1description: 生产服务器
参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#serverObject
Tag 对象
Tag 对象用于对 path 对象中的 API 进行分组,可以更美观的生成文档。
# API 的分组标签
tags: - name: petdescription: 与宠物相关的接口externalDocs:description: 外部文档url: 'http://swagger.io'- name: storedescription: 宠物商店- name: userdescription: 用户操作相关externalDocs:description: 外部文档url: 'http://swagger.io'
参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#tagObject
Path 对象
定义各个的端点和操作的相对路径。这里指定的路径会和 Server 对象 内指定的URL地址组成完整的URL地址,路径可以为空,这依赖于 ACL constraints 的设置。
参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#pathsObject
External Documentation 对象
允许引用外部资源来扩展文档
# 附加文档
externalDocs:description: Find out more about Swaggerurl: 'http://swagger.io'
参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#externalDocumentationObject
Components 对象
包含开放API规范固定的各种可重用组件。当没有被其他对象引用时,在这里定义定义的组件不会产生任何效果
# 一个包含多种纲要的元素,可重复使用组件
components:schemas:responses:parameters:examples:requestBodies:headers:securitySchemes:links:callbacks:
参考:componentsObject
详细节点说明参考:https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md#oasDocument
基于OAS 规范制作文档
在开发团队中会产生很多基于Http协议的服务, 这些服务需要在团队中给测试或者接入方或者对外部表达这些服务接口,往往需要产生一个可以被查看的,或需要可以被调试的界面,这种Http具备要素是既定的,国际上多家大型企业参与并制定OAS的规范,对Http协议的各种属性进行规范表达。更多大家熟知的是不同语言提供的Swagger集成组件,在项目中集成Swagger扩展组件,Swagger会结合语言的一些规范,产生json文档,以及提供可被阅读以及调试的可视化界面,直接使用,非常便利,这样阅读对象就可以很好的阅读并调试对应Http服务的各种接口,市面上Swagger组件即为基于OpenApi规范产生的文档,继而提供基于文档规范的可视化界面,在项目中使用Swagger组件上面就可以看到对应的json文档地址,以及接口的描述
实用过程中,服务如何基于OpenAPI规范产生文档以及可视化界面
具体项目实现可参考:
net core: https://github.com/domaindrivendev/Swashbuckle.AspNetCore
java :https://github.com/swagger-api/swagger-core
php:https://github.com/zircote/swagger-php
项目集成组件之后呈现示例:
二:连接器基于OpenApi的管理能力
服务需要对外表达和描述一个接口,集成平台涉及接口管理的也需要进行表达和描述,其中接口中心和连接中心对接口的表达以及文档的存储都为基于OpenApi规范的json文档,下面描述连接中心模块,如下
示例图:
连接器分两种类型:Http类型连接器,托管连接器
Http 类型连接器:保有现有Http的相关操作,处理授权以及接口表达,通过集成平台的网关进行转发
托管类型连接器:用户操作层面不变(Http协议),集成平台内部实现具体动作,构建连接器管道,网关请求的时候会识别当前连接器的类型,以及规范路由从而进入连接器的管道,实现对应连接器的托管实现
例如:数据库连接器,把这种非Http协议的连接器,对外转化成统一的Http协议接口,数据库连接器提供了两个接口-》查询和写入,用户调用只需要通过接口的形式,最终操作集成平台的连接器实现
Http连接器接口示例:和托管连接器对外实现接口描述一致
基于Http连接器,系统提供自发现&OpenApi 2.0,3.0规范文档的导入实现
背景
大多数用户存在很多这种Http协议的微服务,或者某个服务有很多接口, 用户本身也需要对接口进行表达,并提供使用方调用;现使用集成平台,如果手动添加,或者我们提供一种新的规则导入形式都会给用户带来不小的维护成本,基于种种考虑和用户的真实诉求,集成平台按照国际规范提供基于OAS规范的文档导入,可以给用户减少数据的维护操作,增加便利;下面介绍集成平台的实现逻辑。
1、自发现
用户在创建连接器的时候,系统会自动扫描连接下面的swagger页面,获取页面中对应的json文件地址,读取并解析,然后把每个Api拆分成单个OpenApi规范的json文档进行存储
示例:
2、导入功能
用户可以填写json文档地址,或者上传json文件,提交服务端,读取并解析,然后把每个大的json文档拆分成单个Path组成的OpenApi规范的json文档进行存储
示例:
3、集成系统对API的描述呈现
新建或者自发现或者导入, 在系统存储中,每个Api是一个OpenApi 3.0规范的json文档,页面上面每个Api的详情,即为解析json做界面渲染
组件实现基础介绍
集成平台后端技术主要为net core框架,作为OpenApi规范创始成员之一的微软,对Core框架提供了相对成熟的扩展组件
Microsoft.OpenApi -》提供基于OpenApi规范的构建能力等
Microsoft.OpenApi.Readers-》提供基于OpenApi规范json文档的读取转化能力,以及把对象转发成json字符串的能力等
源码:https://github.com/Microsoft/OpenAPI.NET
构建示例
var document = new OpenApiDocument{ Info = new OpenApiInfo { Version = "1.0.0", Title = "Swagger Petstore (Simple)", }, Servers = new List<OpenApiServer> { new OpenApiServer { Url = "http://petstore.swagger.io/api" } }, Paths = new OpenApiPaths { ["/pets"] = new OpenApiPathItem { Operations = new Dictionary<OperationType, OpenApiOperation> { [OperationType.Get] = new OpenApiOperation { Description = "Returns all pets from the system that the user has access to", Responses = new OpenApiResponses { ["200"] = new OpenApiResponse { Description = "OK" } } } } } }};br
集成平台连接中心Http连接导入功能
实现模式:系统中对接口的描述,每个接口都会有一个独立的文档描述,什么叫独立,独立是指一个OpenApi规范文档的最小粒度,一个Path一个文档
所以我们实现的时候,把一个大的文档,按照Path切割成若干的小文档,并对单条数据进行填充,转化成关系型的数据,例如一个接口会包含:请求类型,名称,请求路径等
流程示意图
核心逻辑演示说明:主要分5步
1、通过地址或者文件读取内容成文本
using (var httpClient = _httpClientFactory.CreateClient()) { string jsonStr = await httpClient.GetStringAsync(address); }文件读取:using (StreamReader reader = new StreamReader(fileStream)) { string jsonStr = await reader.ReadToEndAsync(); }br
2、通过微软提供的组件读取文本,转化成对象
OpenApiDocument openApiDocument= new OpenApiStringReader() .Read(jsonStr, out diagnostic);//说明:diagnostic为OpenApiDiagnostic, 输出值为版本号:2.0或3.0 // 来源nuget库-》Microsoft.OpenApi.Readers // OpenApiDocument 来源nuget库-》Microsoft.OpenApi// OpenApiStringReader 来源nuget库-》Microsoft.OpenApi.Readersbr
3、遍历文档的Path,构建粒度最小的OpenApi规范文档,一个Path对应一个文档
/// <summary>/// 拆分文档,并组装数据/// </summary>/// <param name="list">解析文档成结构化以及主要信息平铺的对象集合</param>/// <param name="openApiDocument">原始的大Document</param>/// <param name="connectionCode">连接编码</param>public static void ConverterSplit(List<ConnectionApiModel> list, OpenApiDocument openApiDocument, string connectionCode){ //校验文档的有效性 if (openApiDocument?.Paths == null || openApiDocument.Paths.Count < 1) return; foreach (var item in openApiDocument.Paths) { //构建Document对象 var docmentEntity = OpenApiOperExtensions.InstantiationSimplified (item.Value.Operations?.FirstOrDefault().Value?.Summary, openApiDocument?.Info?.Version ?? INFO_VERSION, item.Value.Operations?.FirstOrDefault().Value?.Description); //增加单path docmentEntity.AddPath(item); //增加当前Path涉及的Components docmentEntity.AddComponents(openApiDocument.Components, item.Value); //增加当前Path的Security docmentEntity.AddSecuritySchemes( openApiDocument.Components?.SecuritySchemes); //增加默认Schema - 非必须 docmentEntity.AddDefaultSchema(); //解析document对象为文本并添加list对象 Generate(docmentEntity, list, item, connectionCode);}br
构建Document说明
public static OpenApiDocument InstantiationSimplified(string title, string version, string description) { return new OpenApiDocument { Info = new OpenApiInfo { Title = title, Version = version, Description = description }, Paths = new OpenApiPaths(), Components = new OpenApiComponents() }; }br
添加Path说明
public static void AddPath(this OpenApiDocument openApiDocument, KeyValuePair<string, OpenApiPathItem> path) { ArgNullCheck(openApiDocument); if (openApiDocument.Paths == null) { openApiDocument.Paths = new OpenApiPaths(); } if (openApiDocument.Paths.ContainsKey(path.Key)) return; openApiDocument.Paths.Add(path.Key, path.Value); }br
增加SecuritySchemes说明
授权的SecuritySchemes为所有接口公用,拆分过程中,只需要每个最小粒度的文档包含即可。
增加Components
找出当前Path引用的Components,当前操作会稍显麻烦,在真实操作的时候单个Path的参数引用模型是可以是嵌套的模式,在获取当前Path的Ref引用(引用会在Components包含)需要递归操作。
4、组装Api数据,并把单条文档转化成json字符串,便于存入数据库
RequestPath = 解析当前Path的路由Swagger = 当前Path的规范文档(json)ConnectionCode = 连接器业务编码(用户侧填写)ApiName = 接口名称(解析Path的Summery属性得到)Description = 接口描述(解析Path的Description属性)HttpMethod = 请求类型(解析Path的请求类型)
5、入库
集成平台连接中心Http连接导出功能
导出即为导入逆向的操作, 把多个单Document,聚合成一个大的OpenApi规范的Document,进行导出
导出逻辑不做代码演示,和导入动作类似,需要建立新的Document,解析所有需要导出的接口数据,并把接口的规范文档(json存入)通过微软组件对象化,组装成一个总的Json文档,进行输出即可。
总结
导出的逻辑可以各自思考一下
本文章主要想对连接器的导入导出结合OAS规范文档做一些说明
希望大家对OAS规范文档有个初步认识,对集成平台连接器的导入和导出结合OAS规范文档的实现能得到一些收获
参考文章
https://github.com/fishead/OpenAPI-Specification/blob/master/versions/3.0.0.zhCN.md
https://en.wikipedia.org/wiki/OpenAPI_Specification
https://spec.openapis.org/oas/v3.0.3
https://swagger.io/specification/
https://github.com/Microsoft/OpenAPI.NET
------ END ------
作者简介
孙同学: 研发工程师,目前负责集成平台相关研发工作。
也许您还想看:
技术分享|Java SDK动态数据源和上下文机制
技术分享|NodeJS分布式链路追踪实现
更多明源云·天际开放平台场景案例与开发小知识,可以关注明源云天际开发者社区公众号:
【建模】文档服务提供高保真打印模式
明源云·天际硬核技术认可:获华为鲲鹏技术认证书
天际·开发者社区“重装发布”!