自动化代码天生东西 Snips 开辟实践

媒介

在开辟事情中,经常会碰到新产物、效劳上线后,须要将其 API 编写差别言语的 SDK。但差别言语 SDK 中都有很大一部份内容是用来举行 API 的形貌,而且这部份代码量是最大的,手写起来也死板易错。所以我们须要一种 Data-Driven 的开辟体式格局,经由过程东西(Snips)来自动化的天生准确、文雅的代码,让开辟者削减反复无意义的事情,将更多精神放在产物以及营业上。

本文共 4420 字,浏览也许须要 18 分钟。

本日的内容包括:


•    QingStor SDK 简介
•    QingStor SDK 开辟流程的转变
•    API Specification
•    SDK 天生东西 Snips
•    场景化测试
•    运用 Snips 开辟 QingStor Go SDK


正文

人人好,我是青云 QingCloud 体系工程师 Aspire 。本日我来和人人分享一下 QingStor SDK 以及自动化 SDK 天生东西 Snips 的开辟履历。

本日交换的内容包括:

  • QingStor SDK 简介

  • QingStor SDK 的开辟流程

  • API Specification

  • SDK 天生东西 Snips

  • 场景化测试

  • 运用 Snips 开辟 QingStor Go SDK

1. QingStor SDK 简介

QingStor™ 对象存储为用户供应可无穷扩大的通用数据存储效劳,在 QingCloud Console (青云掌握台)中可以直接建立、运用和治理对象存储 Bucket ,可以轻易的上传下载文件。我们也供应了敕令行东西(如 qingcloud-cli, qsctl) 来在种种场景下举行数据的存取。然则面临海量数据的操纵时,图形化的界面和敕令行东西是不够的。别的,我们的用户也须要在代码层面运用 SDK 或许直接要求 API 来接入 QingStor 对象存储。自上线以来我们就开放了一套范例、范例且简约的 RESTful API ,以及一个 Python 的 SDK 。虽然说 Python 的用户量异常大,然则显著只要这一种的 SDK 是没法满足用户需求的,再加上 QingStor 的 API 是遵照 RESTful 范例的,直接运用 API 来接入 QingStor 的本钱也会高一些。(不过幸亏我们已在本年上半年兼容了 AWS S3 的 API ,所以用户也可以运用 S3 的 SDK 来接入 QingStor 。)

这里将 QingStor API 和 QingCloud IaaS 的 API 做个简朴比较:

《自动化代码天生东西 Snips 开辟实践》

相比之下用户运用 API 来接入 QingStor 的难度会高一些,对 SDK 的需求也就更猛烈。

如今 QingStor 供应了包括 Go 、 JavaScript 、 Ruby 、 PHP 、 Swift 、 Java 、 Python 在内 7 种言语的 SDK ,已可以做到掩盖主流编程言语,而且有了 Snips 的协助,开辟者也可以在短时刻内开辟出另一种言语的 SDK 。

同时,此次我们将 QingCloud IaaS 和 QingStor 的 SDK 举行了拆分,比方 qingcloud-sdk-swift (还没有宣布) 和 qingstor-sdk-swift 。如许做主假如斟酌到挪动端对空间比较敏感,所引入的第三方库越小越好,由于 QingCloud IaaS 如今开放的 API 数目是 QingStor 的三倍,将二者合并为一个包会形成空间的糟蹋,关于一个仅须要 QingStor 做为存储的 App 来说,只引入 QingStor 的 SDK 就充足了。

QingStor SDK 的中文运用文档可以参考 https://docs.qingcloud.com/qi… ;别的这些 SDK 也已开源在 GitHub ,可以接见 https://github.com/yunify 来猎取,也迎接人人给我们提 Issue 和 Pull Request 。

2. QingStor SDK 的开辟流程

起首可以回忆一下我们 Python SDK 的开辟体式格局,就是在 API 发作转变以后,手动增添 SDK 中与之对应部份的代码,这类做法效力不高,保护起来也让人头疼。

再加上 QingCloud IaaS 和 QingStor 共有两百多个开放 API ,而且不停有新的 API 陪伴产物或功用上线,要做到 SDK 的及时跟进比较难题。而且如今只要一个 Python 的 SDK ,假如再加上其他言语的,每种言语都手动保护,会消耗工程师许多不必要的精神。另有一个题目比较贫苦,假如有用户对一些小众言语的 SDK 有需求,我们也没法马上举行支撑,这点行业内基本都有相似的状况。

要处置惩罚这些题目,就须要换一种思绪。我们可以看到,差别言语的 SDK 中都有很大一部份内容是用来举行 API 的形貌(或许叫定义),而且这部份代码量是最大的,手写起来死板易错。所以我们采纳了一种新的 SDK 的开辟流程,运用范例的数据来天生代码,以后经由过程场景化的测试来举行考证,个中用到了我们自身写的一个代码天生东西━━ Snips 。

Snips 运用 API 的范例化形貌和代码模版来天生种种言语 API 挪用的那部份代码,除了天生出来的代码,还须要手动编写的代码,每种言语都不一样,不适合一致天生代码,比方错误处置惩罚,文件读写,收集要求等。如许做比起纯手工打造一个 SDK ,须要开辟的代码量会小许多,开辟效力可以获得很大的提拔。

上面是应用 Snips 开辟一种新的言语的 SDK 的示意图。下面详细申明一下。

新增一种言语的 SDK :

  • 手写哪些错误处置惩罚、收集要求等相干的的代码

  • 编写代码模版

  • 运用 Snips 天生代码

  • 经由过程场景化测试

  • 宣布

更新 SDK :

  • 更新 API 形貌

  • 从新天生代码

  • 经由过程场景化测试

  • 宣布

这里的 API 的形貌我们是经由过程 Git Submodule 的情势引入到各个 SDK 项目中,如许假如是 API 的变动,完整不须要手动编写 SDK 的代码就可以做到 SDK 的更新。

下面会逐一讲一下 API 形貌范例 ( API Specification )、 Snips 和 场景化测试( Scenario Based Testing )这几个部份,我们是如何做的。

3. API Specification

要完成上述的流程,得先有 API 的形貌,我们花了很长时刻来肯定运用如何的 API 形貌范例,也走了一些弯路。

早先我们自身制订了一个 API Specification 的 Schema :

  • 这个 Schema 的目的是形貌 HTTP API

  • 每个 API Specification 文件显现一个 Service (如 QingCloud IaaS 或许 QingStor )

  • Service 中可以有 SubService

  • 同时 Service 和 SubService 中都包括 Metadata 、 Properties 、 Operations 、 Endpoint 等信息

  • Operation 是详细的 API 要求,个中包括 Request 和 Response 的形貌以及其他基本信息

  • 定义了 boolean 、 integer 、 timestamp 、 binary 、 list 、 object 等几种基本的数据范例,及自定义的数据范例 CustomizedType, CustomizedType 可以涌现多级援用

以后运用这套 Schema ,去形貌了 QingStor 的 一切 API ,而且写了剖析器,疾速完成了从 API 形貌天生 Go SDK 的代码。然则 Review 时我们发明这个自身定义的 Schema 照样太大略,没有经由充足的数据举行考证,许多状况都没有斟酌到,另有一些 Corner Case 也难以形貌,而且这个 Schema 自身的校验效果也不抱负。而且假如运用这套自身定义的 Schema 来形貌 QingStor 和 QingCloud API ,无论是在内部运用照样开放出去,都是让人比较难以接收的,这类自立门户的做法也没有太大意义。

然后我们对比了几个如今可以用到的几个 API Specification 的范例,末了挑选了 Swagger 。

Swagger 是一个形貌 RESTful API 的范例, Swagger 详细的 Specification 人人可以接见它的网站来检察: http://swagger.io

本年的一月份 Swagger 更名为 OpenAPI Specification ,由 Linux 基金会资助成立了 OpenAPI Initiative 来继承 OpenAPI Specification 的开辟。在 Google 、 Microsoft 等大厂的支撑下, Swagger 仿佛已成了业界范例,相干的生态和东西也已比较完全,用它来作我们 API 的形貌范例再适宜不过,所以我们终究挑选了 Swagger 来从新形貌了 QingStor APIs ,而且完成了用 Swagger 形貌范例来天生代码。

运用 Swagger 范例无疑是准确的,由于 Swagger 的东西和生态相对比较完善。以 Swagger Editor 为例,它是一个 API Specification 的 Web 编辑器,可以在编辑的同时供应代码补全、高亮和及时语法考证功用,感兴趣的朋侪可以在 http://editor.swagger.io 体验一下。

Swagger 虽然生长的比较快,但并非对一切 API 都友爱。 QingCloud IaaS 的 API ,要求参数部份里会有数组( Array )和字典( Map )。比方 statics.n.router_static_name 、 statics.n.router_static_value 这类要求参数,用户现实供应的是一个由 Static 字典构成的数组,而且这个要求参数是位于 Request URL Query , SDK 会把数组和字典转换一下花样,构造出 statics.0.router_static_name=name&statics.0.router_static_value=value 这类情势的要求串。如许就会涌现题目,在形貌要求的时刻须要定义数组和字典参数,由于 Swagger 的范例比较严厉, Operation Parameter 不允许自定义范例涌现,这时候就只能将要求参数的形貌放在 Request Body 内里来定义,如许就须要剖析 Specification 的时刻做一些特别处置惩罚。

Swagger 范例也斟酌到了 API 数目许多致使形貌文件太长的状况,它支撑运用 $ref 来援用其他文件,固然这个援用的功用现实上是 JSON Reference 和 JSON Pointer 范例供应的,然则这里的 $ref ,只支撑同一个文件内的援用,或许是援用某个 URL 链接。我们测试的剖析器,包括 Swagger 官方的 swagger-codegen 都不支撑文件间的援用,更不必提 Circle Reference 这类经常使用的状况了。不过这个题目我们在 Snips 中也处置惩罚掉了,可以看到我们的 QingStor API Specs 中的 API 形貌是拆分成了许多文件的,详细内容等下 Snips 的部份会提到。

运用 Swagger API Specification 范例来形貌 API ,其作用不单单议可以用来天生代码,天生文档,更主要的是它的束缚作用,它反过来可以范例 API 的开辟和托付,进一步保证 QingCloud 的团体效劳质量。关于 SDK 开辟来说则是一种 Data-Driven 的开辟体式格局,这类思绪可以让产出的各个 SDK 在功用上坚持很强的一致性,不会涌现某种言语的 SDK 缺失功用,或许是更新滞后,这类思绪的上风也会跟着更多产物和功用的上线变得愈来愈显著。

API Specification 文件自身也须要考证准确性,而运用 Swagger 范例可以易如反掌的运用 JSON Schema 来完成 Specification 数据的考证。

QingStor 的 API Specification 也放到了 GitHub ,这里是地点 https://github.com/yunify/qin…

4. 代码天生东西 Snips

接着讲讲代码天生东西,关于 Swagger 来说,有官方的代码天生器 swagger-codegen ,另有其他的同类开源项目比方 go-swagger 。

它们虽然说可以天生代码,然则天生出来的代码可控性和可读性都不高,并不能满足我们的需求,定制起来也比较贫苦。

比方采纳 swagger-codegen 得 fork 过来,改它的 Java 代码,而且每增添一种言语的 SDK 基本上都要去增添对应的 Java 代码,这关于 Java SDK 以外的开辟者来说是异常不友爱的。

除此以外另有许多其他细节上的题目,比方我们 API 的遗留题目,上面说到的 QingCloud IaaS 的要求参数不范例;比方 swagger-codegen 和 go-swagger 不支撑文件援用的剖析;天生出来的代码大小写掌握不严厉( acl 被转换成了 Acl ,而不是 ACL )等。

现有的代码天生器没有可以开箱即用的,都须要去举行不少的修正。然则去完成一个 Swagger 的剖析器又太费时辛苦了,所以我们想到了一种折衷的设计,运用开源的 Swagger 剖析器来构建自身的天生器。

比对了几个开源项目以后,我们采纳的剖析器是 go-openapi/spec ( https://github.com/go-openapi/), 这个剖析器的作者也是 go-swagger 的作者, go-swagger 是在这个剖析器之上构建的。遗憾的是 go-openapi 也不支撑文件援用,看到将来有支撑文件援用功用的设计,不过不知道什么时刻才会加上。因而我们简朴熟习了一下代码,以后提交了几个 PR 把这功用帮他们完成了,作者也欣然接收 “ With this PR go-swagger is the first library on go that fully supports json schema and ref resolving so very happy with it ?”。

随后就有了代码天生东西 Snips ,它是一个敕令行东西,很好地支撑着我们的 SDK 开辟,以 Go 言语 SDK 为例,包括模版在内,手写的代码约莫 6 千行摆布,而天生出来的代码已达到了 2 万多行,开辟效力获得了不小的提拔。

关于模版, Snips 会从指定途径加载模版文件,模版目次下须要有一个 manifest 文件,可所以 JSON 或许 YAML 花样,这个文件指定了一些天生划定规矩,比方指定该目次下模版文件的花样,输出文件名的定名作风是 CamelCase 照样 snake_case ;输出文件的扩大名和前后缀,可以参考 example 下的 manifest.yaml 来检察一切支撑的划定规矩。模版文件花样如今只支撑一种,是 Go 言语的 template 。

与代码天生有关的简朴逻辑是放在模版里去完成的,同时天生器也供应了一些内置函数可以在模版中运用,如大小写作风的转换、字符串替代、数据通报等,从而做到了天生器与某种言语无关,新增言语不须要去修正天生器的代码。上文提到的 acl 转换成 Acl 的题目,运用 Snips 供应的函数就可以准确转换,比方 {{snakeCase “acl”}} 会转换成 “ ACL ”。

关于多版本 API , Snips 也有处置惩罚设计。

经由过程 -n (–service-api-version) 参数来指定运用的 API 版本,然后将代码天生到差别的目次,比方 latest version 的代码在 service 目次,特定版本的代码可以在 service-2016-01-06 中,再依据言语的差别看是不是还须要响应的调解。以 Go 言语为例,用户运用的时刻 import 差别的途径的 service 即可切换差别版本的 API ,如 import “github.com/yunify/qingstor-sdk-go/service-2016-01-06″。

Snips 如今已开源, GitHub 地点: https://github.com/yunify/snips 。如今是针对 QingCloud IaaS 和 QingStor API 的代码天生东西, Snips 的思绪和其他的 Swagger 天生器的思绪不太一样,将来也可能会做成一个通用的代码天生器。

5. 场景化测试

SDK 开辟出来了,除了单元测试以外,还须要在线上临盆环境举行测试,保证托付的 SDK 可一般事情,我们称之为效劳测试( Service Test )。

效劳测试中我们采纳 Cucumber ( https://cucumber.io),它是一个 Behaviour-Driven Development (BDD) 东西。 Cucumber 会读取经由过程自然言语形貌的测试场景和数据,然后连系差别的测试完成去考证是不是经由过程。 Cucumber 可以被称作是一种测试体式格局,基本上每种言语都有它的完成。

举个例子:
《自动化代码天生东西 Snips 开辟实践》

猎取一个 Object , Cucumber 形貌是如许的:
《自动化代码天生东西 Snips 开辟实践》

Ruby 中对应的测试完成是如许的:
《自动化代码天生东西 Snips 开辟实践》

Cucumber 会搜检代码场景实行过程当中的数据是不是满足预期,给出一个完成的测试效果

如许以运用者的角度来实在的测试 SDK ,而且可以让一切 SDK 的测试用例坚持一致,在保证 SDK 质量的同时,也可以做到种种言语 SDK 功用的一致性。

QingStor SDK 的测试场景也放在了 GitHub : https://github.com/yunify/qin…

6. 运用 Snips 开辟 QingStor Go SDK

上面讲了整套的 QingStor 的 SDK 开辟流程,下面用 QingStor Go SDK 来举例申明一下。

qingstor-sdk-go https://github.com/yunify/qin…

起首须要完成 SDK 最基本的部份,比方收集要乞降署名处置惩罚、文件读写、错误处置惩罚等等,然后再运用 Snips 天生 API 相干的代码。

假定基本部份如今已完成了,而且经由了单元测试。

接下来装置 Snips ,可以运用 go get -u github.com/yunify/snips 装置,或许直接接见 GitHub 下载编译好的二进制文件。

在代码堆栈目次下以 git submodule 的情势引入 API Specification 和 Test Scenarios:

./specs/qingstor 援用 QingStor API specifications
./test/features 援用 QingStor 测试场景

然后便可编写代码模版,下图所示为 Go SDK 的模版文件:
《自动化代码天生东西 Snips 开辟实践》

详细的模板文件内容请见:
https://github.com/yunify/qin…

模板编写完成后,即可应用模版和 API Specifications 来天生代码。下图为天生代码的敕令,天生完的代码有可能会丢脸,可以花样化一下代码,固然假如模版掌握的严厉,天生出来的代码充足美丽,可以跳过花样化的步骤。
《自动化代码天生东西 Snips 开辟实践》

以后便可运用这些天生好的代码,完成测试场景,详细的代码请见这里: https://github.com/yunify/qin…
《自动化代码天生东西 Snips 开辟实践》

末了运转测试
《自动化代码天生东西 Snips 开辟实践》

7. 开辟者鼓励运动

如今 QingStor 已供应了七种言语的 SDK (个中 Python SDK 的新版也会运用 Snips 来从新天生),掩盖了主流的编程言语,但另有一些编程言语的 SDK 我们没有来得及开辟,为鼓励更多的开辟者介入进来孝敬别的言语的 SDK ,我们特此提议 QingStor SDK 大赛运动,报名地点请见: https://jinshuju.net/f/0MB6w6

    原文作者:青云QingCloud
    原文地址: https://segmentfault.com/a/1190000007873237
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞