在本期 Swagger 聚焦中,Tristan Sokol,Square 的开发者倡导者,讲述了他的团队如何使用 Swagger Codegen 生成 SDK。要提交您自己的 Swagger 聚焦主题,请点击此处。
Square 的开发者平台团队与大多数团队略有不同。
我们没有为我们的开发者产品构建单独的 API,而是专注于公开我们第一方产品使用的 API,从而为开发者创造无缝的体验。
我们有许多上游团队是我们面向外部 API 的利益相关者,他们不断希望公开新功能并进行改进。
这是决定我们如何构建 SDK 时的一个重要因素;我们不希望我们的团队成为瓶颈,产品团队必须等待我们完成 SDK 的更新才能发布新功能。
我们避免这种情况的主要方法是通过 SDK 生成。
SDK 生成
我们没有手动编写每个 SDK(这不仅耗时、容易出错,还会减慢将新功能发布到 SDK 中的速度),而是使用一种高度依赖 SDK 生成的过程。有许多 SDK 生成方式,因此如果您正在考虑为您的 SDK 采用类似的方法,请务必查看各种可能性,找到最适合您的方案。
我们首选的方式是使用 OpenAPI 规范来定义我们的 API 端点,并使用 Swagger Codegen 以编程方式生成 SDK 的代码。
API 规范
我们使用 OpenAPI(以前的 Swagger 规范)标准来定义我们的 API。对我们来说,这是一个 JSON
文件,它定义了 URL、要发出的 HTTP 请求类型,以及为每个 API 端点提供或期望返回的信息类型。我们的规范由 3 个主要部分组成:通用信息/元数据、路径和模型。
通用信息/元数据
规范的这一部分包含 API 的一些描述性信息,例如您可以在哪里找到许可信息,或者联系谁寻求帮助。
"info": {
"version": "2.0",
"title": "Square Connect API",
"description": "Client library for accessing the Square Connect APIs",
"termsOfService": "https://connect.squareup.com/tos",
"contact": {
"name": "Square Developer Platform",
"email": "[email protected]",
"url": "https://squareup.com/developers"
},
"license": {
"name": "Apache 2.0",
"url": "https://apache.ac.cn/licenses/LICENSE-2.0.html"
}
},
路径
这些描述了 API 的各个端点(或 URL 路径)。它描述了要发出的 HTTP
请求类型、如何进行授权,以及应向请求添加的信息类型,以及应期望返回的信息类型。
在下面的示例中,您可以看到它是一个 POST
请求,URL 中有几个必需的参数,正文中还有另一个参数,并且您会收到一个 CreateRefundResponse
对象。
"/v2/locations/{location_id}/transactions/{transaction_id}/refund": {
"post": {
"tags": [
"Transactions"
],
"summary": "CreateRefund",
"operationId": "CreateRefund",
"description": "Initiates a refund for a previously charged tender.\n\nYou must issue a refund within 120 days of the associated payment. See\n(this article)[https://squareup.com/help/us/en/article/5060] for more information\non refund behavior.",
"x-oauthpermissions": [
"PAYMENTS_WRITE"
],
"security": [
{
"oauth2": [
"PAYMENTS_WRITE"
]
}
],
"parameters": [
{
"name": "location_id",
"description": "The ID of the original transaction\u0027s associated location.",
"type": "string",
"in": "path",
"required": true
},
{
"name": "transaction_id",
"description": "The ID of the original transaction that includes the tender to refund.",
"type": "string",
"in": "path",
"required": true
},
{
"name": "body",
"in": "body",
"required": true,
"description": "An object containing the fields to POST for the request.\n\nSee the corresponding object definition for field details.",
"schema": {
"$ref": "#/definitions/CreateRefundRequest"
}
}
],
"responses": {
"200": {
"description": "Success",
"schema": {
"$ref": "#/definitions/CreateRefundResponse"
}
}
}
}
},
模型
模型描述了 API 与之交互的不同对象。它们主要用于将 API 的 JSON 响应序列化为每种语言的本机对象。在这个 CreateRefundResponse
中,您可以看到它由几个其他模型组成,以及描述,甚至还有一个响应示例。
"CreateRefundResponse": {
"type": "object",
"properties": {
"errors": {
"type": "array",
"items": {
"$ref": "#/definitions/Error"
},
"description": "Any errors that occurred during the request."
},
"refund": {
"$ref": "#/definitions/Refund",
"description": "The created refund."
}
},
"description": "Defines the fields that are included in the response body of\na request to the [CreateRefund](#endpoint-createrefund) endpoint.\n\nOne of `errors` or `refund` is present in a given response (never both).",
"example": {
"refund": {
"id": "b27436d1-7f8e-5610-45c6-417ef71434b4-SW",
"location_id": "18YC4JDH91E1H",
"transaction_id": "TRANSACTION_ID",
"tender_id": "TENDER_ID",
"created_at": "2016-02-12T00:28:18Z",
"reason": "some reason",
"amount_money": {
"amount": 100,
"currency": "USD"
},
"status": "PENDING"
}
},
"x-sq-sdk-sample-code": {
"python": "/sdk_samples/CreateRefund/CreateRefundResponse.python",
"csharp": "/sdk_samples/CreateRefund/CreateRefundResponse.csharp",
"php": "/sdk_samples/CreateRefund/CreateRefundResponse.php",
"ruby": "/sdk_samples/CreateRefund/CreateRefundResponse.ruby"
}
},
您可以在 GitHub 上的 Connect-API-Specification 存储库中查看我们迄今为止最新版本的规范。
规范是我们生成过程的重要组成部分,因为它是关于我们的 API 如何工作的真实来源。当其他团队想要扩展其 API、发布新 API 或只是提高模型描述的清晰度时,他们可以对此单个文件进行编辑,并将其更改传播到所有客户端 SDK。
我们实际上是从描述内部服务到服务通信的文件中生成我们的大部分规范,以实现更多的流程自动化和更容易的更改。
Swagger Codegen
现在我们已经准备好 API 规范,我们如何将其转换为面向客户端的 SDK?答案是 Swagger Codegen。Swagger Codegen 是一个由 Smartbear 支持的开源项目(就像其他 Swagger 工具一样),它将您的 OpenAPI 规范应用于一系列不同语言的 SDK 模板,并进行少量配置。
模板
模板使用一种称为 mustache 的语言来定义其各个部分,并且在大多数情况下,看起来和读取起来都像目标语言中的文件。下面是我们的 PHP SDK 模板的一部分。您可以看到,代码注释等有用的内容也会自动生成,以便最终的 SDK 可以内置文档、代码片段等。
<?php
{{#models}}
{{#model}}
/**
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen
* Do not edit the class manually.
*/
namespace ;
use \ArrayAccess;
/**
* Class Doc Comment
*
* @category Class
* @package
* @author Square Inc.
* @license https://apache.ac.cn/licenses/LICENSE-2.0 Apache License v2
* @link https://squareup.com/developers
*/
class implements ArrayAccess
{
...
配置
这些实际上不那么复杂,本质上是小的 json
文件,描述了您的 SDK 的各个方面,通常是关于它如何适应相关的包管理器。
{
"projectName": "square-connect",
"projectVersion": "2.8.0",
"projectDescription": "JavaScript client library for the Square Connect v2 API",
"projectLicenseName": "Apache-2.0",
"moduleName": "SquareConnect",
"usePromises": true,
"licenseName": "Apache 2.0"
}
由于 Codegen 项目非常活跃,我们实际上为我们支持的每个 SDK 签入一份模板文件副本,并固定到特定的 Codegen 版本,以确保我们不会因为所有自动化而意外地将重大更改推送到我们的用户。
您可以在与我们的规范文件相同的存储库中查看驱动 {Java、PHP、C#、Python、Ruby、JavaScript} SDK 的所有模板和配置文件:Connect-API-Specification。
其他想法
我们的流程已经发展了很多,Travis CI 等工具在流程中产生了很大的影响。您可以使用 CI 和 CD 工具来使流程更加自动化,但请确保您有一套良好的测试覆盖率,以帮助防止意外更改潜入您发布的代码中。
希望您喜欢了解我们的 SDK 生成过程。您也可以观看我在 DevRelCon 上就此主题发表的录音演讲 这里。如果您想了解更多关于我们的 SDK 或 Square 的其他技术方面的信息,请务必关注此 博客、我们的 Twitter 帐户,并注册我们的 开发者新闻通讯!
这篇文章也发表在 Square 的技术博客 上 - 查看以了解更多信息
Swagger 聚焦是 Swagger 社区成员与其他社区成员分享他们的见解和项目的机会。 了解更多关于您如何成为下一个特色人物的信息!