TeaDSL:支持任意 OpenAPI 网关的多语言 SDK 方案

uploading.4e448015.gif正在上传…重新上传取消lADPD3IrqdwdnI_NAs3NBDg_1080_717.jpg

导读

在以云计算为主角的开发者视界中,OpenAPI 是绝对的主角。要发短信,用 OpenAPI;要管理资源,用 OpenAPI;要管理权限,用 OpenAPI。如果一个 OpenAPI 解决不了你的问题,那就再来一个。在今天,开放平台及 OpenAPI 随处可见,它是系统与系统之间集成的重要桥梁。但 OpenAPI 用起来是否真的舒服,这要打一个大大的问号。本文将介绍 OpenAPI 领域下的难题和一些解决方案。

背景

阿里云有位工程师叫朴灵,热爱开源,是活跃在 Github 上的国内技术大牛之一。在阿里工作 6 年之际,朴灵产生了离职的想法,打算去一家创业公司再战高峰。走之前,朴灵做了一些研究工作,他发现阿里云在功能和产品上可以说是一流的云计算厂商,是创业公司的首选,但由于过去的业务中写过大量的 Node.js SDK,对开发者体验有着自己的体感,他觉得在开发者体验关怀上,阿里云做得还不够好。来自一个热血工程师最朴素的想法,自己何不先留下来,去把这件事情做好,于是,朴灵加入了阿里云开放平台负责 SDK 业务,期间,他和团队研发了专利 TeaDSL,下面朴灵将分享 TeaDSL 如何解决多语言 SDK 的问题。

使用 OpenAPI 的痛苦

在过去,我们经常说的 OpenAPI,通常的做法是,开发好服务端的接口,然后在文档里简单写几个参数描述,就直接丢给客户去用。反正我是开发好了,我这里是好的,客户能不能用起来我是不用管的。

 

92cefbfe390343e2b16e1b9be54afe12.pnguploading.4e448015.gif正在上传…重新上传取消lALPD4d8objEnJRjzQGz_435_99.png
图 1 第一代的 OpenAPI 通常仅由简单的文档及实际的接口构成

然而接下来的问题就来了。首先,文档上写得不清不楚的参数,没有试过,完全不知道它到底能不能 Work。其次,OpenAPI 总得有一定的权限认证吧,那么总得有一个签名啥的,每个客户都要写一遍,关键是总是没法写对。再次,不同的客户所使用的编程语言不一样,得把接口重新包装才能用。

总算费心费力调通了接口,以为可以高枕无忧的时候,咋接口老是报错,网络连不上,返回的数据不对,诸如此类。再往后,OpenAPI 可能总是要发生一点变化什么的,总是出现一些数据结构发生变化,不兼容之类的问题。

一个 OpenAPI 到最后,不光是用户使用起来觉得很气,作为维护者也是很艰难的。当公布一个 OpenAPI 后,第一步给出简单的文档后,会发现除了要把参数详情写得越来越完善准确外,还得给出签名算法,让不同语言的开发者来接入。然而给出签名算法后,会发现只有一些开发者能顺利完成,大部分的开发者只能眼巴巴地请你帮忙提供一个 SDK。好吧,那就提供一下我最拿手的 Java 语言的签名,提供一个核心 SDK 呗。

 

lALPD4d8objEnJrMzs0CkA_656_206.png
图 2 第二代的 OpenAPI 会有 SDK 的实现,但仅有少许的语言支持

随着这个 OpenAPI 接口的用户越来越多,一个客户说我要用 C++ 来对接你,另一个客户说我要用 Python 来对接你,于是,我一个 Java 程序员,怎么就要写那么多语言的 SDK 呢。没有办法,如果不提供良好的 SDK,客户说,没有 IDE 提示呢,我怎么写代码呢。

总而言之,在 OpenAPI 的应用过程中,一件简单的事情,会变得非常复杂:

  • 需要提供良好的 API 文档,作为最基本的要求
  • 需要提供 SDK,保障开发者的编码体验,封装细节,代码提示等
  • 需要提供 Code Sample,更理解接口的使用效果
  • 如果有 CLI 就更好了,这样连 bash 脚本写起来也更方便
  • 如果没有 Test Cases 作为日常的持续集成,接口质量可能存在问题

上面这些要求,如果加上多种编程语言的条件,就会演变为一件细碎而又繁多的体力活。并且这中间不能有任何的变动,因为仅仅是一点点的 OpenAPI 变动,就需要连带整个下游发生变化。如果一个地方没有保持一致,那么客户问题就会出现。

 

c705f4b7ebf7419eb8599543066d11c6.pnguploading.4e448015.gif转存失败重新上传取消lALPD3IrqdwdnKLNAQrNAm0_621_266.png
图 3 当用户量变多,OpenAPI 的提供者需要提供完善的工具及更多的编程语言支持

通常为了解决此类的问题,以及 OpenAPI 的诸如签名校验,限流,生成 SDK、文档等等,业界通常会使用 API 网关来承担这些横向的责任。

然而,作为笔者所在的环境下,会发现,我们身边的网关有点多。于是不同的网关有不同的风格,不同的签名算法,不同的序列化格式。于是上述的过程要根据不同网关的数量,进行翻倍:

 

lALPD4d8objEnKnNAQrNA3E_881_266.png
图 4 当一个企业变得庞大时,不同风格的 OpenAPI 及网关都会出现

当我们在抱怨使用不同产品的 OpenAPI/SDK 体验不一致,文档不对,Demo 出错等等问题时,真不是因为做这些事情太难,而是太多,太琐碎。一件简单的事情,需要做一百次,也就不是简单的事情了。

TeaDSL 的解决之道

TeaDSL 是由阿里云开放平台 SDK 团队主导设计的一门领域特定语言。主要用于解决如下问题:

  • 通过一门中间语言,可以支持不同风格的网关。即使网关下的 OpenAPI 风格各异,也能一致地表达到。
  • 可以通过翻译的能力,实现对不同编程语言的代码生成。也就是可以基于统一的中间表达,生成多语言的 SDK。
  • 基于中间表达,我们可以将一组 OpenAPI 视为一个 library,因此可以在这个基础上实现 OpenAPI 接口的 Code Sample 编写。进而实现多语言的 Code Sample 统一生成。

因此 TeaDSL 的核心能力就是通过一种中间语法来描述 OpenAPI,提供类似编程语言的能力,来将 OpenAPI、SDK、Code Sample 等场景及语言有机地结合在一起。

在没有 TeaDSL 之前,对于不同的网关,我们要为它制定独立的工作流程,即从 OpenAPI 定义到不同语言的 SDK 生成,是独特的。换一个新的网关风格,就要重新实现这套流程。

 

26bd791dc1ad4994bfb072ee782d0048.pnguploading.4e448015.gif正在上传…重新上传取消
图 5 M 个网关都要支持 N 种编程语言,整个工作量是 M * N 的关系

而具有 TeaDSL 后,我们则形成一个中间层。可以将原来的工作收敛起来,我们仅需要关注不同的网关到 TeaDSL 的转换工作,以及 TeaDSL 到各个编程语言的生成工作。

 

lALPD3lGpyWqnLHNATXNAZk_409_309.png
图 6 经过中间层的隔离,整个工作量变为 M + N 的关系

也就是说,TeaDSL 是在做一件 M * N 到 M + N 的工作。当网关越多,支持的编程语言越多,收益则越大。

一旦这个中间层建立起来,整个 OpenAPI 的应用形式都可以基于它来构建。比如,编写一个 OpenAPI 的 Code Sample,Test Case 等。

接下来简单介绍 TeaDSL 是如何实现支持任意风格的网关和多种编程语言的。

如何支持任意风格的网关

对于不同的 API 网关,或者不同产品的 OpenAPI 而言,它们之间的风格可能都千差万别,因此在很大的程度上,每种风格的 OpenAPI 都有它自己的元数据定义格式。为了减少网关、风格带来的差异化,业界主要推动的方式是尽量采用标准的定义格式。比如 Swagger 就是其中的佼佼者,它依托于 OpenAPI Specification ,以 RESTful 风格的 OpenAPI 作为基准,形成了一套业界标准。

但这个世界就是这样不完美,我们现有的大量 OpenAPI 并不是 RESTful 风格的。这导致很多的产品现存的 OpenAPI 在文档、SDK等场景下,无法使用上 Swagger 这样强大的生态工具链。

为了解决这些问题,我们需要进行两步操作:

  • 设立一套新的标准,来包容不同风格的 OpenAPI
  • 以这套新的标准,来建设生态工具链

如果完成这两个步骤,那么现实世界上的每一个 OpenAPI,RESTful 或者非 RESTful 的,不需要做任何迁移,也能具有强大的工具链支持。

新标准的设计

通过我们的研究发现,无论 OpenAPI 的参数是如何组成的,传输是 JSON,还是 XML,乃至自定义协议,OpenAPI 都是基于 HTTP 协议栈进行提供的。也就是说,万变不离其宗的是 HTTP 协议本身。因此我们确立的基本模型是这样的:

{protocol: string, // http or httpsport: number,         // tcp porthost: string,         // domainrequest: {method: string, // http methodpathname: string, // path namequery: map[string]string, // query stringheaders: map[string]string,  // request headersbody: readable      // request body},response: {statusCode: number, // http methodstatusMessage: string, // path nameheaders: map[string]string,  // response headersbody: readable      // response body},
}

对于不同风格的 OpenAPI 而言,就像不同风格的建筑,它们的建筑材料都几乎相同,只是施工手法,组合形式不一样而已。我们看到的 OpenAPI 风格差异,实质则是序列化过程不同而带来的不同。我们序列化过程和数据模型分离,将用户更直观的数据结构提取出来。

比如从用户角度出发,一个数据模型是更直观的事物:

model User {username: string,age: number
}

在不同的网关下,它的传输形式可能是 JSON,也可能是 XML,但最终都是 readable,也就是可读的字节流。

toJSON(user: User): string
toXML(user: User): string

最终的结果就是:

__request.body = toJSON(user);
__request.body = toXML(user);

更进一步的过程是,我们会将一个 OpenAPI 的请求/响应包装为一个类似于编程代码的方法:

api getUser(username: string): User {__request.method = 'GET';__request.pathname = `/users/${username}`;__request.headers = {host = 'hostname',};
} returns {var body = readAsJSON(__response.body);return body;
}

尽管上面的代码不能实际运行,但大致也看出来我们包容不同的网关、风格的办法如下:

  • 以 request / response 也就是 HTTP 协议作为核心模型
  • 通过引入一些方法,如 toJSON / toXML / readAsJSON 等方法来分离数据结构和序列化过程
  • 将整个过程包装成方法

这些方法在不同的编程语言下具有不同的实现,但我们只要定义好统一的签名,就能确保一致性:

function toXML(data: $Model): string;
function toJSON(data: $Model): string;

以上就是 TeaDSL 如何实现支持任意网关的方案。整个过程相对抽象,网关间的那些具有差异化的风格,统统交给这些方法去实现,留下来的就只有数据结构。

如何支持不同的编程语言

如果只是能通过一种描述方式来描述不同的 OpenAPI 调用过程,只是完成了一半的工作。另一半的工作是如何将这种描述语言落地到不同的编程语言下。在过去,我们支持不同的编程语言,主要是基于模版的形式来生成不同语言的实际代码。但这对我们来说仍然还有一些不足之处:

  • 模版的生成方式相对生硬,实现起来容易,但维护起来不那么灵活
  • 生成出来的代码容易带来命名冲突,语法错误等

从上面的形式也看到,这个方案,被我们设计成了一种 DSL 代码。因此它是具有自己的词法、语法、语义规则的,在生成目标编程语言代码之前,会有一套自身的校验。DSL 的这些能力是模版所不具备的。

可能对于别的场合,采用 DSL 的形式并不多见。但对于前端工程师而言,这些年已经见的较多了:CoffeeScript、Babel、JSX、TypeScript 等等。为此我们参考了诸多编程语言的设计,最终形成了自己的一套语法。并借鉴编译器领域的转译方式,因此我们可以在模型一致的情况,生成到各种不同的编程语言下。

整个 TeaDSL 的处理流程如下:

 

lALPD3W5KIDkHLbNAgLNAZk_409_514.png

最终我们支持多种编程语言的场景主要有3个:

  • 基本的多种语言的 SDK
  • OpenAPI 相关的多种语言的 Code Sample
  • OpenAPI 相关的多种语言的 Test Case

通过中间语言的强校验,生成到多种目标场景,可以解决编程语言支持不全面的问题。同时也大幅节约 OpenAPI 维护者的精力成本,不需要反复手工地编写不同编程语言下的 Code Sample。随着对不同编程语言的支持逐步完善,这些中间 TeaDSL 代码不需要任何操作,即可自动支持到新的编程语言下。

总结

TeaDSL 的主要能力是支持到不同风格的 OpenAPI,同时支持多语言的 SDK、Code Sample 目标生成。最终的目的仍然是打通从 OpenAPI 定义到文档、到 SDK、CLI 等 OpenAPI 使用场景下的一致性。提供给用户更统一、专业、一致的使用体验。同时也大幅降低 OpenAPI 提供者用来支持用户的成本,通过自动化的方式,节省精力的同时,还减少人为参与时导致的错误。

目前 TeaDSL 在阿里云的一些 SDK 上已经有所应用,如:https://github.com/aliyun/aliyun-ccp。阿里云开放平台在持续努力提升它的整个工具支持生态,以期望能建成比 Swagger 更适配的生态体系。

原文链接

本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/516318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue如何循环提取对象数组中的值

数据如下,提取name和callcount 第一种: getQueryCallStatistics("sesp1", this.provinceId).then((res) > {let arr [];let arr1 [];let arr2 [];let arr3 [];let arr4 [];this.xunshiMap res.data.callstatistics;res.data.callst…

Node.js 从门详解 (二)

目录1. 模块化的基本概念1.1 什么是模块化1.2 模块化规范2. Node.js 中模块化2.1 Node.js 中模块的分类2.2 加载模块2.3 Node.js中的模块作用域2.3.1 什么是模块作用域2.3.2 模块作用域的好处2.4 对外共享模块作用域中的成员2.4.1 module对象2.4.2 module.exports对象2.4.3 共享…

分享实录 | 阿里巴巴测试环境管理实践概述

正在上传…重新上传取消 【以下为分享实录,有删节】 测试环境管理之困 正在上传…重新上传取消 互联网产品的服务通常是由 Web 应用、中间件、数据库和许多后台业务程序组成,一套运行环境就是一个自成一体的小生态。部署软件产品的正式发布版本&#…

高校毕业生:今年“太惨了”,网友:更惨的可能还在后头!

受疫情影响,今年的就业形势基本上没跑了:“各行各业,大小企业,全面缩招!”据国家统计局7月份的最新数据显示:20-24岁大专及以上人员(主要为新毕业大学生)失业率比去年同期高 3.3 个百…

uniapp利用腾讯地图接口获取当前定位城市及计算两经纬度的实际距离

文章目录一、注册腾讯地图1. 申请开发者密钥(key)2. 开通webserviceAPI服务3. 下载SDK二、导入SDK2.1. 解压复制2.2. 页面导入三、实现3.1. 先创建实例。3.2. 获取经纬度3.3. 监控四、计算二点距离4.1. 官网地址4.2. 代码4.3. 测试一、注册腾讯地图 1. …

Gartner 企业级网络设备市场份额报告:阿里云负载均衡增速全球第一

4月8日,Gartner发布最新的全球企业级网络设备市场份额报告,阿里云负载均衡(SLB)增速全球第一,单季度营收环比增长35.1%,远超欧美传统厂商或是云服务厂商。 负载均衡被誉为IT系统的流量管家,它可…

放弃 Windows 后 ,开源操作系统能成为主流桌面系统吗?

来源 | CSDN责编 | 郑丽媛头图 | CSDN下载自东方IC在近十几年里,总是能听到世界各地的国家或者地方政府在尝试用开源系统代替Windows作为政府办公系统,尤其在今年微软正式宣布停止对Windows 7的更新维护服务后,很多数年来一直使用的Windows 7…

Sentinel 1.7.2 发布,完善开源生态及扩展性

Sentinel 1.7.2 正式发布,带来了 Logger SPI 扩展机制、Zuul 2.x 网关流控、SOFARPC 适配等多项特性和改进。下面我们来一起探索一下 Sentinel 1.7.2 的重要特性。 多样化的适配模块 到目前为止,Sentinel 已覆盖微服务、API Gateway 和 Service Mesh 三…

微信开发者工具:Failed to load font ************** net::ERR_CONNECTION_RESET问题解决办法

如果微信开发者工具前几天用的好好的突然出现 VM541:1 Failed to load font https://img.yzcdn.cn/vant/vant-icon-d3825a.ttf net::ERR_CONNECTION_RESET 这个错误说明。可能原因是微信开发者工具发布了新版本,你需要更新一下开发工具的版本,就能解决这…

从 DevOps 到 NoOps,Serverless 技术的落地方式探讨

Serverless 技术正以一种全新的方式,帮助云上客户进一步节省云的使用成本,实践 NoOps 理念,同时,他也正深刻变革着开发者们的编程模式,所谓“Write locally, compile to the cloud”。 本文将介绍 Serverless 技术来降…

uni-app中使用腾讯位置服务实现小程序地图选点功能

文章目录1. 官方文档2. 小程序添加插件3. HBuilder配置4. 配置代码5. 页面代码1. 官方文档 技术选定(地图选点插件) (对应官网:https://lbs.qq.com/miniProgram/plugin/pluginGuide/locationPicker ) 2. 小程序添加…

8000字 | 32 张图 | 一文搞懂事务+隔离级别+阻塞+死锁

来源 | 悟空聊架构(ID:PassJava666)头图 | CSDN下载自视觉中国事务1.1 什么是事务为单个工作单元而执行的一系列操作。如查询、修改数据、修改数据定义。1.2 语法「(1)显示定义事务的开始、提交」BEGIN TRANINSERT IN…

uni-app中使用腾讯地图sdk(解析经纬度)获取用户所在位置信息

前言: 技术选定 https://lbs.qq.com/dev/console/custom/apply 具体步骤: 注册开发者账号、申请密钥、开通webserviceAPI服务、下载小程序SDK、微信后台配置请求request域名。 ( 请按官方完成以上操作:https://lbs.qq.com/mini…

4月数据库流行度排行出炉:MySQL 成事实王者

2020年4月DB-Engines 数据库流行度排行出炉。在本月的排行榜上,Oracle 较上月微涨 4.78 分,MySQL 微涨 8.62 分,甲骨文公司成为最大赢家。而微软的两个产品 Microsoft SQL Server 下降 14.43 分,Microsoft Access 下降 3.22分&…

MySQL 在 Mac 环境下的安装

目录 Mac 系统配置 MySql 数据库1. 安装 MySql 数据库2. 安装 MySql Workbench 可视化工具Mac 系统配置 MySql 数据库 1. 安装 MySql 数据库 1.1 双击打开安装包 mysql-8.0.19-macos10.15-x86_64.dmg: 1.2 双击 mysql-8.0.19-macos10.15-x86_64.pkg 运行安装包,并点击 继续…

微信小程序console.log出来的是object的问题解决方法

在开发微信小程序的时候,从后台传过来的数据没有问题,但是在开发的过程中,console.log出来的结果为object。 解决方案: 把加好改为逗号,即可

超大福利 | 这款免费 Java 在线诊断利器,不用真的会后悔!

线上系统为何经常出错?数据库为何屡遭黑手?业务调用为何频频失败?连环异常堆栈案,究竟是哪次调用所为? 数百台服务器意外雪崩背后又隐藏着什么?是软件的扭曲还是硬件的沦丧? 走进科学带你了解 A…

面试官:因为这个语言,我淘汰了90%的人!!

很多人都有这样的经历:大量重复性工作;日报、周报、各种报,无穷无尽;不计其数的数据提取琐碎繁杂的事务让工作的效率极低。如果可以一键完成就好了。对这些问题来说,最高效的解决途径就是 Python。1991 年,…

MySQL在Windows 环境中的安装

文章目录 MySQL 在 Windows 系统下的安装MySQL 在 Windows 系统下的安装 双击 mysql-installer-community-8.0.19.0.msi,启动 MySQL 安装程序。 如果弹框提示如下的警告信息,证明你的电脑需要安装额外的 .NET Framework 依赖包。此时,先退出 MySQL 的安装程序,然后双击 ND…

灵魂发明家自述:我就是靠这个创业成功的

扫描二维码,了解低代码的高科技 原文链接 本文为云栖社区原创内容,未经允许不得转载。