多語言 SDK 生成

說起生成多語言 SDK,大家第一時(shí)間想起的一定是當(dāng)前業(yè)界內(nèi)生成多語言 SDK 的通用方案——Swagger,開發(fā)者通過 Swagger 定義的 OpenAPI 標(biāo)準(zhǔn)并配合模板的方式來生成多語言 SDK。不過問題并沒有因此而得到完美的解決。首先模版的生成方式相對生硬,雖然實(shí)現(xiàn)起來容易,但維護(hù)起來卻不那么靈活;其次,大量 OpenAPI 并不是 RESTful 風(fēng)格的,這就導(dǎo)致很多產(chǎn)品現(xiàn)存的 OpenAPI 在文檔、SDK 等場景下,無法使用上 Swagger 這樣強(qiáng)大的生態(tài)工具鏈。既然無法沿用 Swagger 規(guī)范元數(shù)據(jù)的方法來解決這個(gè)問題,我們就需要對我們的工作重新進(jìn)行抽象。在筆者看來,之所以沒有一套元數(shù)據(jù)可以適用于所有的網(wǎng)關(guān)主要還是因?yàn)槊總€(gè)網(wǎng)關(guān)所對應(yīng)的后端情況不同,就像機(jī)器語言或者匯編語言會(huì)因?yàn)榧軜?gòu)的不同而有所不同,但是其本質(zhì)還是描述如何通過操作寄存器、內(nèi)存里的數(shù)據(jù)來完成一個(gè)程序,高級語言就是通過 AST 兼容了各平臺(tái)的這些不同最后解決了這些問題。而對于 OpenAPI 來說也是同樣的道理,所以我們通過重新定義一門 DSL 語言 Darabonba 來描述各種各樣的 OpenAPI。

通過 Darabonba 對 OpenAPI 進(jìn)行描述,其本質(zhì)就是統(tǒng)一了元數(shù)據(jù),只是這個(gè)元數(shù)據(jù)并不是 JSON 或者 Yaml 這樣的方式來描述的,而是通過 DSL 代碼來描述。Darabonba 的編譯器則會(huì)將 Darabonba 的 DSL 代碼轉(zhuǎn)化為 AST,通過 OpenAPI 描述轉(zhuǎn)化而來的 AST 不僅包含了 OpenAPI 的信息,而且還包含整個(gè) OpenAPI 的流程性描述,所以我們只需要通過 AST 開發(fā)對應(yīng)的各語言SDK就可以生成多語言的 SDK了。Darabonba 具體的設(shè)計(jì)思路和理念可參考文章:Darabonba:支持任意 OpenAPI 網(wǎng)關(guān)的多語言 SDK 方案,這里就不再贅述。

模塊化設(shè)計(jì)

在通過元數(shù)據(jù)向生成 SDK 的過程中,僅僅通過對 OpenAPI 的數(shù)據(jù)模型和請求/響應(yīng)描述是不夠的,還需要各種參數(shù)處理,簽名生成,文件上傳,流操作等各種復(fù)雜的方法,以往通過模板生成 SDK 的時(shí)會(huì)選擇維護(hù)一個(gè)各語言的核心模塊來封裝這些方法,但是隨著支持的 OpenAPI 越來越多核心庫中的方法也是越來越多,就會(huì)產(chǎn)生以下的問題:

在通過 Darabonba 生成的 SDK 時(shí)也會(huì)遇到同樣的問題,Darabonba 作為一門 DSL 語言主要能力在于描述 OpenAPI ,為了保障生成的 SDK 具備完整的功能同樣需要很多實(shí)現(xiàn)很多核心方法,而在總結(jié)以往維護(hù)核心庫的中遇到的問題以后,我們選擇了現(xiàn)在在高級語言中非常常見的模塊化開發(fā)理念,并提供了相應(yīng)的命令行工具 Darabonba CLI 和 Darabonba 模塊倉庫。

接口模塊

Darabonba 其核心能力是描述 OpenAPI,缺少復(fù)雜邏輯實(shí)現(xiàn)的能力,為了彌補(bǔ)這個(gè)能力 Darabonba 設(shè)計(jì)了接口模塊的概念。與 Java 中的 interface 接口類型定義類似,Darabonba 的接口模塊即是只在 Darabonba 編寫的DSL 代碼中只定義方法體的集合而并不實(shí)現(xiàn)其具體邏輯,真正的邏輯則是由各語言分別實(shí)現(xiàn)。例如 Darabonba 中常用的 Console 模塊:

/**
* Console val with log level into stdout
* @param val the printing string
* @return void
* @example \[LOG\] tea console example
*/
static function log(val: string): void;

我們只需要在模塊中申明模塊包含 log 方法并描述它的出參入?yún)⒓纯桑髡Z言則通過自身語言的特性來實(shí)現(xiàn)該方法即可,其具體實(shí)現(xiàn)可參考 Console 模塊源碼。在編寫好生成接口模塊以后可以通過 Darabonba 提供的 Darabonba CLI 執(zhí)行?dara publish?將模塊發(fā)布到 Darabonba 模塊倉庫,就可以在 Darabonba 代碼中使用了。下面就是我們通過引入 Console 模塊來打印字符串的一段代碼:

import Console;

static async function main(args: [ string ]) throws : void {
Console.log("hello world!");
}

通過接口模塊的設(shè)計(jì)理念將以往核心庫中的方法根據(jù)功能拆分成一個(gè)個(gè)包含了特定功能的基礎(chǔ)模塊,不僅使得生成的 SDK 更好用邏輯更清晰,同時(shí)也做到了足夠的抽象避免很多在生成 SDK 過程中重復(fù)造輪子的工作。目前 Darabonba 官方提供了包含了常用方法的 Util 模塊、文件上傳所使用的 FileForm 以及 XML 模塊等,同時(shí)開發(fā)者也可以編寫與自己業(yè)務(wù)邏輯相關(guān)的接口模塊并發(fā)布到 Darabonba 模塊倉庫。

OpenAPI 模塊

在 Darabonba 的模塊化設(shè)計(jì)中不止有接口模塊,事實(shí)上每一個(gè) Darabonba 的項(xiàng)目都是一個(gè)模塊,所以基于一組 OpenAPI 描述編寫的 Darabonba 代碼就是一個(gè) OpenAPI 模塊。開發(fā)者在完成了 OpenAPI 描述的 Darabonba 代碼編寫以后,同樣可以通過 Darabonba CLI 將描述 OpenAPI 的 Darabonba 模塊發(fā)布到模塊倉庫中,這樣使用 SDK 的用戶就可以通過模塊的詳情頁面查看 SDK 中包含的方法及各語言 SDK 的安裝說明等信息了。


基于一組 OpenAPI 發(fā)布的 Darabonba 模塊不僅可以幫助用戶更好的了解這組 OpenAPI,更可以在這個(gè)基礎(chǔ)上實(shí)現(xiàn) OpenAPI 接口的 Code Sample 編寫,進(jìn)而實(shí)現(xiàn)多語言的 Code Sample 統(tǒng)一生成。

Code Sample 自動(dòng)生成

可以說對于簡單的 API 調(diào)用普通的 API 文檔就足夠了,但是隨著現(xiàn)在 OpenAPI 在系統(tǒng)與系統(tǒng)集成之間使用的越來越廣泛,其復(fù)雜度也隨之提高,以往單純使用 API 文檔的方式已經(jīng)不足以讓客戶順利的使用 OpenAPI 了。從阿里云目前的工單情況來看,SDK 相關(guān)的客戶咨詢至少有一半是因?yàn)闆]有 Code Sample 造成的,其中更是有1/4的客戶是直接要求為 SDK 提供 Code Sample。

這種情況下,能夠提供給用戶可運(yùn)行、可調(diào)試的 Code Sample 示例就成了文檔中必不可少的一部分,但是如何能夠編寫全語言的 Code Sample 并且保障其可運(yùn)行,卻是一個(gè)極大的問題。如果通過人力來維護(hù),很容易就出現(xiàn)語言不全,或是編寫的代碼沒有維護(hù)的問題,阿里云中遇到最多的問題就是 OpenAPI 在迭代,而 Code Sample 卻忘記迭代了造成了提供出去的 Code Sample 無法使用從而被用戶詬病。

通過引用模塊倉庫中 Darabonba 模塊編寫的 CodeSample 則可以避免這樣的問題,首先多語言的自動(dòng)生成,節(jié)約了大量的維護(hù)成本,而且風(fēng)格統(tǒng)一利于用戶理解;同時(shí) Darabonba 編譯時(shí)采用類型的強(qiáng)校驗(yàn),一旦 OpenAPI 的參數(shù)或者返回結(jié)果出現(xiàn)了不兼容的更新,CodeSample 則會(huì)生成失敗從而通知到開發(fā)者更新相關(guān)示例來解決這個(gè)問題。下面是阿里云語音服務(wù) SDK 相關(guān)的 CodeSample 示例,大家也可以點(diǎn)擊示例鏈接嘗試生成:

import Dyvmsapi;
import RPC;
import Console;

/**
* 使用AK&SK初始化賬號(hào)Client
* @param accessKeyId
* @param accessKeySecret
* @param regionId
* @return Client
* @throws Exception
*/
static function createClient (accessKeyId : string , accessKeySecret : string) throws : Dyvmsapi{
var config = new RPC.Config{};
// 您的AccessKey ID
config.accessKeyId = accessKeyId;
// 您的可用區(qū)ID
config.accessKeySecret = accessKeySecret;
return new Dyvmsapi(config);
}

/**
* @param args
* @throws Exception
*/
static async function main(args: [string]) throws : void {
var client = createClient("accessKeyId","accessKeySecret");
var request = new Dyvmsapi.QueryCallDetailByCallIdRequest{
// 通話的唯一識(shí)別ID。
callId = "100625930001^10019107xx",
// 產(chǎn)品ID。
// 11000000300006:語音通知。
// 11010000138001:語音驗(yàn)證碼。
// 11000000300005:語音IVR。
// 11000000300004:語音雙呼。
// 11000000300009:語音SIP。
// 11030000180001:智能外呼。
prodId = 11000000300004L,
// 指定通話發(fā)生的時(shí)間,格式為Unix時(shí)間戳,單位毫秒。會(huì)查詢這個(gè)時(shí)間點(diǎn)對應(yīng)的一整天的記錄。queryDate = 1577255564
};
var response = client.queryCallDetailByCallId(request);
Console.log(response.code);
}

Test Cases 自動(dòng)生成

OpenAPI 公布上線以后,如何能夠保障 OpenAPI 持續(xù)可用就是一個(gè)非常重要的問題,如果沒有一個(gè)保障機(jī)制,很可能會(huì)出現(xiàn) OpenAPI 出了問題就無法及時(shí)發(fā)現(xiàn),客戶的投訴也就隨之而來。而且 OpenAPI 和 SDK 也會(huì)遇到更新升級等情況,如何能保障這些更新升級不會(huì)給正在使用 OpenAPI 的客戶造成問題也是 OpenAPI 提供方遇到的一個(gè)非常大的挑戰(zhàn)。為了解決這些挑戰(zhàn), 就需要 OpenAPI 提供方編寫 Test Cases 作為日常的持續(xù)集成來檢驗(yàn) OpenAPI 的可用性,但是目前多語言的 SDK 的 Test Cases 大多存在以下的問題:

需要大量的人力去維護(hù) Test Cases ,而且無法保障所有語言的 SDK 都擁有 Test Cases;

OpenAPI 的 Test Cases 少且更新頻率低,造成了對 OpenAPI 的覆蓋面低而無法起到有效的保障作用;

各語言 SDK 的由各語言的開發(fā)同學(xué)分別維護(hù),所以用例不同步導(dǎo)致不同語言之間的測試結(jié)果有所差異。

而Darabonba 的多語言生成能力則可以解決以上所有問題,只需要引用 SDK 在模塊倉庫中對應(yīng)的 Darabonba 模塊與 Darabonba 官方提供的斷言模塊 Assert 模塊編寫對應(yīng)的 Darabonba Test Cases 即可為各語言 SDK 生成其對應(yīng)的 Test Cases。通過 Darabonba 自動(dòng)化生成 Test Cases 不僅可以解決人力不足 Test Cases 很難覆蓋各語言 SDK 的情況,而且生成的各語言 Test Cases 標(biāo)準(zhǔn)一致,也可以解決各語言 Test Cases用例不同步造成的測試差異問題。下面是一段通過 Darabonba 編寫的測試用例:

import Assert;
import Dyvmsapi;
import RPC;

static function createClient (accessKeyId : string , accessKeySecret : string) throws : Dyvmsapi{
var config = new RPC.Config{};
config.accessKeyId = accessKeyId;
config.accessKeySecret = accessKeySecret;
return new Dyvmsapi(config);
}

static async function TestNumberEqual() throws : void {
var client = createClient("accessKeyId","accessKeySecret");
var request = new Dyvmsapi.QueryCallDetailByCallIdRequest{
callId = "100625930001^10019107xx",
prodId = 11000000300004L,
queryDate = 1577255564
};
var response = client.queryCallDetailByCallId(request);
Assert.equal(response.code, 'OK', 'queryCallDetailByCallId is failed!');
}

Darabonba 的主要能力是支持到不同風(fēng)格的 OpenAPI,同時(shí)支持多語言的 SDK、Code Sample 目標(biāo)生成。最終的目的仍然是打通從 OpenAPI 定義到文檔、到 SDK、CLI 等 OpenAPI 使用場景下的一致性。提供給用戶更統(tǒng)一、專業(yè)、一致的使用體驗(yàn)。同時(shí)也大幅降低 OpenAPI 提供者用來支持用戶的成本,通過自動(dòng)化的方式,節(jié)省精力的同時(shí),還可減少人為參與時(shí)導(dǎo)致的錯(cuò)誤。

參與貢獻(xiàn)

Darabonba 的目標(biāo)是讓用戶得到極致的 OpenAPI 體驗(yàn),所以我們也需要更多的人參與到我們的開源項(xiàng)目來,大家可以按以前的方式參與 Darabonba 的貢獻(xiàn):

參與其他語言生成器的生成,目前 Darabonba 只支持了比較常用的六門語言,還需要更多生成器的支持。

文章轉(zhuǎn)自微信公眾號(hào)@阿里云開發(fā)者

熱門推薦
一個(gè)賬號(hào)試用1000+ API
助力AI無縫鏈接物理世界 · 無需多次注冊
3000+提示詞助力AI大模型
和專業(yè)工程師共享工作效率翻倍的秘密
返回頂部
上一篇
微服務(wù)架構(gòu)中API的開發(fā)與治理
下一篇
Toapi,一個(gè)讓?API?調(diào)用更簡便的?Python?庫!
国内精品久久久久影院日本,日本中文字幕视频,99久久精品99999久久,又粗又大又黄又硬又爽毛片
国产一区激情在线| 国产精品资源在线观看| 久久久久久久久99精品| 久久久国产精华| ...xxx性欧美| 亚洲国产成人av网| 激情综合五月天| 97se亚洲国产综合自在线不卡 | 97久久精品人人做人人爽 | 日韩激情在线观看| 成人免费黄色大片| 欧美一区二区国产| 中文字幕一区在线| 精品国产区一区| 久久久久久久电影| 亚洲情趣在线观看| 国内外成人在线视频| 一本色道久久综合亚洲aⅴ蜜桃| 欧美一级精品在线| 亚洲欧美成人一区二区三区| 精品系列免费在线观看| 欧美在线你懂的| 欧美精品一区视频| 亚洲香肠在线观看| 国产精品123区| 制服视频三区第一页精品| 国产精品入口麻豆原神| 免费国产亚洲视频| 在线观看视频一区二区欧美日韩| 国产婷婷色一区二区三区四区 | 国产精品美女久久久久高潮| 日韩精品五月天| 91九色最新地址| 国产欧美中文在线| 加勒比av一区二区| 91精品国产丝袜白色高跟鞋| 亚洲在线成人精品| 欧美性xxxxx极品少妇| 一区在线播放视频| jlzzjlzz亚洲女人18| 国产精品日韩成人| 96av麻豆蜜桃一区二区| 18成人在线视频| 日本丰满少妇一区二区三区| 亚洲精品一卡二卡| 一本高清dvd不卡在线观看| 中文字幕中文字幕中文字幕亚洲无线| 国产传媒日韩欧美成人| 国产日韩综合av| 粉嫩欧美一区二区三区高清影视| 国产婷婷精品av在线| 成人免费福利片| 亚洲欧美日韩系列| 欧美日韩国产综合久久| 日韩**一区毛片| 精品国产免费久久| 高清不卡在线观看| 欧美激情一区三区| 日本电影亚洲天堂一区| 日韩不卡一区二区| 久久久久亚洲综合| 在线这里只有精品| 日韩精品欧美成人高清一区二区| 日韩欧美国产1| 成人午夜av电影| 一区二区三区四区乱视频| 精品视频999| 精品一二三四区| 国产精品另类一区| 欧美视频在线观看一区| 精品亚洲免费视频| 久久 天天综合| 色婷婷激情综合| 亚洲一区二区三区中文字幕在线| 色88888久久久久久影院按摩| 亚洲精品高清在线| 欧美日本高清视频在线观看| 久久精品噜噜噜成人av农村| 国产亲近乱来精品视频| 欧美性大战久久久久久久蜜臀| 日本 国产 欧美色综合| 欧美激情综合在线| 欧美日韩大陆在线| 国产69精品久久久久777| 日韩电影网1区2区| 亚洲蜜臀av乱码久久精品| 日韩欧美一区二区三区在线| 97久久精品人人做人人爽 | 久久99久久久久久久久久久| 欧美激情一区在线| 69成人精品免费视频| 成人午夜在线播放| 久久精品国产一区二区三| 一区二区三区不卡视频| 久久人人97超碰com| 欧美疯狂做受xxxx富婆| 色诱亚洲精品久久久久久| 韩国女主播成人在线| 亚洲一区二区三区视频在线播放| 中文字幕国产一区| 国产色一区二区| 国产亚洲午夜高清国产拍精品 | 国产激情一区二区三区四区| 日韩成人av影视| 午夜不卡av免费| 中文字幕在线播放不卡一区| 中文字幕的久久| 久久毛片高清国产| 久久新电视剧免费观看| 欧美精品一区二区三区蜜臀| 欧美一区二区三区白人| 51午夜精品国产| 欧美一区二区播放| 精品奇米国产一区二区三区| 日韩一区二区三区在线观看| 日韩欧美精品三级| 亚洲精品一区二区三区蜜桃下载| 精品三级在线看| 久久久无码精品亚洲日韩按摩| 久久免费看少妇高潮| 国产丝袜在线精品| 亚洲国产高清aⅴ视频| 亚洲欧美在线另类| 亚洲精品视频在线看| 亚洲mv在线观看| 免费成人结看片| 韩国视频一区二区| 成人性生交大合| 一本大道久久a久久精二百 | 日韩成人精品在线| 精品亚洲免费视频| 成人小视频免费观看| 在线视频国产一区| 日韩一本二本av| 国产精品―色哟哟| 亚洲国产精品一区二区www| 日本一道高清亚洲日美韩| 激情五月婷婷综合| 色婷婷激情综合| 日韩欧美成人激情| 国产精品久久久久久久久免费相片| 亚洲蜜臀av乱码久久精品| 婷婷综合久久一区二区三区| 国产伦精品一区二区三区免费 | 欧美午夜电影一区| 久久综合一区二区| 国产精品毛片久久久久久久| 亚洲成av人片www| 国产精品综合一区二区三区| 欧美视频在线观看一区| 国产亲近乱来精品视频| 午夜电影网亚洲视频| 国产精品18久久久久久久网站| 在线观看国产精品网站| 久久久久国产精品人| 午夜精品福利在线| 不卡的电影网站| 精品国产露脸精彩对白| 亚洲一区在线观看免费观看电影高清| 国内精品伊人久久久久av影院| 色天使久久综合网天天| 国产午夜精品久久久久久免费视 | 久久综合九色综合97_久久久| 一区二区三区视频在线看| 国产一区二区不卡老阿姨| 欧美久久一二区| 亚洲欧美电影院| 成人涩涩免费视频| 欧美mv日韩mv国产网站| 日本欧美在线观看| 欧美日韩精品福利| 亚洲午夜国产一区99re久久| 99在线视频精品| 中文字幕电影一区| 国产99久久久国产精品| 久久这里只有精品首页| 免费人成在线不卡| 555www色欧美视频| 日韩国产精品久久| 91精品国产欧美一区二区18| 日韩电影一区二区三区| 欧美一区二区三区视频免费| 日韩激情视频在线观看| 精品视频在线免费看| 图片区日韩欧美亚洲| 91精品国产综合久久久蜜臀粉嫩| 午夜精品一区二区三区免费视频 | 激情小说亚洲一区| 精品日产卡一卡二卡麻豆| 激情五月激情综合网| 久久久不卡网国产精品二区 | 亚洲视频一二三区| 色综合色综合色综合色综合色综合 | 欧美一区二区观看视频| 日韩福利视频导航| 久久免费的精品国产v∧| 成人动漫视频在线| 亚洲成av人片在线| 久久久一区二区| 99天天综合性|