Schema-First API 设计
Schema-first API 设计
API 规范语言
OpenAPI 规范语言
结束语
附录
在yos.io上查找更多有趣的文章
本指南向您介绍 Schema-First API 设计领域以及如何开始使用 OpenAPI 生态系统。
您正在构建 API。
您开发了一个包含几个端点的后端服务,并将其部署到生产环境。您发布了几个官方特定语言的 API 客户端以及一份 API 文档。这一天圆满结束。
第二天,API 中将添加一项新功能。您必须:
- 更新服务器实现以支持新功能。
- 更新所有客户端库(每个支持的平台和语言一个 SDK)。
- 更新文档。
- 以上各项必须相互一致。
- 此外,在后端 API 完成之前,前端团队将被阻止。
你重重地叹了口气。
有没有更好的方法可以做到这一点?
对于 API 的每次更改,都必须执行多个步骤,以确保所有开发工件彼此一致。官方支持的 API 客户端 SDK 必须支持最新的 HTTP API 端点。文档也必须与实际实现保持一致。
这些步骤中的每一个步骤都是劳动密集型且容易出错的。因此,将这些任务自动化是合理的,这样我们就可以专注于实际的功能构建。问题是:怎么做?
我们不是直接进行开发,而是从API 规范开始。
Schema-first API 设计
Schema-first API 设计方法主张在编写任何代码之前,先使用多种 API 规范语言之一编写 API 定义。编写 API 规范有几个好处:
改进的 API 设计
API 规范代表 API 的合同。
借助 API 规范和 Swagger UI 等工具,您可以实现 API 可视化,以便其他开发者和利益相关者能够尽早学习并提供设计反馈。您甚至可以根据 API 规范运行模拟服务,以便其他团队可以立即进行交互。
在编写任何代码之前识别设计中的问题比在实施之后再这样做更高效、更简化。
在多个团队之间更快地进行迭代
有了 API 规范,涉及多个团队(后端、网络、移动等)的开发项目可以比传统方法更快地进行。
无论后端组件是否准备就绪,前端团队都可以立即开始构建组件,因为我们可以根据 API 规范生成并运行模拟服务。团队可以并行工作,而不会受到其他团队进度的阻碍。
为您的 API 创建测试
您的 API 规范提供了一份契约,描述了当有人调用您的 API 时,成功的响应是什么样子的。此契约可以重新用于生成测试用例,从而大幅减少测试 API 所需的工作量。您可以根据 API 规范创建功能测试并运行模拟服务。
生成代码和文档
模式优先方法创建了单一事实来源,可用于生成各种开发工件。定义明确的 API 规范可用于自动构建 API、生成 API 参考以及与 API 通信的客户端 SDK。
概括
采用 schema-first API 设计的初始成本较小,但从中获得的收益却非常显著。
API 规范语言
API 规范语言定义了 REST API 的与语言无关的标准表示形式。API 规范语言的示例包括OpenAPI、API Blueprint和RAML。
在下一节中,我们将研究 OpenAPI 规范语言及其周围的工具。
OpenAPI 规范语言
概述
API 是现代应用程序之间的连接纽带。几乎每个应用程序都使用 API 来连接企业数据源、第三方数据服务或其他应用程序。创建一种与供应商无关、可移植且开放的 API 服务描述格式,对于加速实现真正互联世界的愿景至关重要。
OpenAPI 是一种基于 JSON/YAML 的 API 规范语言和框架,用于描述、生成、使用和可视化 RESTful Web 服务。OpenAPI 的首要目标是使客户端和文档系统能够与服务器同步更新。
OpenAPI 和 Swagger 有什么区别?
OpenAPI 是该规范的正式名称。该规范的开发由OpenAPI 倡议组织 (OpenAPI Initiative)推动,该倡议组织由来自科技界不同领域的 30 多个组织组成,其中包括微软、谷歌、IBM 和 CapitalOne。领导 Swagger 工具开发的 Smartbear Software 公司也是 OpenAPI 倡议组织的成员,致力于引领该规范的演进。
Swagger 是一些最知名、最广泛使用的 OpenAPI 规范实现工具的名称。OpenAPI 3.0 规范基于 Swagger 2.0 规范。Swagger 工具集包含开源、免费和商业工具,可用于 API 生命周期的不同阶段。
OpenAPI 提供的不仅仅是一种规范语言,生态系统中的其他工具还包括:
- Swagger 编辑器: Swagger 编辑器允许您在浏览器中编辑 YAML 中的 OpenAPI 规范并实时预览文档。
- Swagger UI: Swagger UI 是 HTML、Javascript 和 CSS 资产的集合,可以从符合 OAS 的 API 动态生成漂亮的文档。
- Swagger Codegen:允许根据 OpenAPI Spec 自动生成 API 客户端库(SDK 生成)、服务器存根和文档。
- Swagger Inspector: API 检查工具,可让您从现有 API 生成 OpenAPI 定义
入门
OpenAPI 规范允许您描述 API,包括(除其他外):
- 有关 API 的一般信息
- 可用路径(例如
/resources
) - 每条路径上可用的操作(例如
GET /resources/{id}
) - 每个操作的输入/输出
以下是 YAML 中的最小 OpenAPI 规范:
openapi: 3.0.0
info:
title: Sample API
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
version: 0.1.9
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
paths:
/users:
get:
summary: Returns a list of users.
description: Optional extended description in CommonMark or HTML.
responses:
'200': # status code
description: A JSON array of user names
content:
application/json:
schema:
type: array
items:
type: string
OpenAPI 3.0 规范的根级别包含 8 个部分。这些根级别对象中嵌套了许多对象,但在根级别,只有以下这些对象:
openapi
:必需。OpenAPI文档使用的 OpenAPI 规范版本的语义版本号(例如3.0.0
.)。info
:必需。提供有关 API 的元数据。servers
:服务器对象数组,为目标服务器提供连接信息。components
:用于保存规范的各种模式的元素。security
:声明可以在 API 中使用哪些安全机制。tags
:规范使用的带有附加元数据的标签列表。externalDocs
:额外的外部文档。paths
:必填。API可用的路径和操作。
您可以使用在线Swagger 编辑器来继续操作!
让我们简单看一下上述每个部分。
该info
部分
该info
对象提供有关 API 的元数据。
info:
title: Sample Pet Store App
version: 1.0.1
description: This is a sample server for a pet store.
termsOfService: http://example.com/terms/
contact:
name: API Support
url: http://www.example.com/support
email: support@example.com
license:
name: Apache 2.0
url: http://www.apache.org/licenses/LICENSE-2.0.html
记得在在线Swagger 编辑器上尝试一下!
该servers
部分
此servers
部分指定 API 服务器和基本 URL。您可以定义一个或多个服务器,例如生产服务器和沙盒服务器。
servers:
- url: https://my-api.com
description: Production server
- url: https://beta.my-api.com
description: Beta server
- url: https://some-other.my-api.com
description: Some other server
在 Swagger UI 上,用户将能够从此预定义列表中选择要发送请求的服务器:
该components
部分
组件是一组可供其余 API 重用的对象,例如:
架构对象
基于JSON 模式的输入和输出数据类型定义。
全局components/schemas
部分允许您定义 API 中使用的通用数据结构。每当需要模式时(在参数、请求主体和响应主体中),都可以通过 $ref 引用它们。
例如这个 JSON 对象:
{
"name": "Garfield",
"type": "Cat"
}
可以表示为:
components:
schemas: # Schema object definition
Pet:
type: object
properties:
name:
type: string
petType:
type: string
required:
- name
- petType
并在其他地方引用$ref: '#/components/schemas/Pet'
。
了解有关OpenAPI 数据模型的更多信息。
响应对象
操作的不同 HTTP 响应代码的预期响应。
components:
responses:
ListPetsSuccessResponse:
description: A an array response with headers
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Pet'
headers:
X-Rate-Limit-Limit:
description: The number of allowed requests in the current period
schema:
type: integer
参数对象
/users/{userId}
操作可以通过 URL 路径 ( )、查询字符串 ( /users?role=admin
)、标头 ( X-CustomHeader: Value
) 或 Cookie ( )传递参数Cookie: debug=0
。您可以定义参数的数据类型、格式、必需还是可选以及其他详细信息:
# A path parameter of string value
name: username
in: path
description: username to fetch
required: true
schema:
type: string
# A header parameter with an array of 64 bit integer numbers:
name: token
in: header
description: token to be passed as a header
required: true
schema:
type: array
items:
type: integer
format: int64
示例对象
example
以下是响应主体中关键字的示例:
responses:
'200':
description: A cat object.
content:
application/json:
schema:
$ref: '#/components/schemas/Pet' # Reference to an object
example:
# Example properties of the referenced object
name: Garfield
type: Cat
其他组件对象
您还可以在该部分中定义安全方案、标头、链接(超媒体)和回调(webhook)对象components
。
组件摘要
的使用components
完全是可选的。它最适用于以可重用的方式存储任何常用的领域对象。
除非从组件对象外部的属性明确引用,否则组件对象内定义的所有对象都不会对 API 产生影响。
该security
部分
该security
对象指定提交请求时使用的安全或授权协议。OpenAPI 支持以下身份验证方法:
- HTTP 身份验证:Basic、Bearer 等。
- API 密钥作为标头或查询参数或包含在 Cookie 中
- OAuth 2
- OpenID Connect 发现
在 OpenAPI 文档的根级别,添加一个安全对象,该对象定义我们用于安全的全局方法:
security:
- API-Key: []
在components
对象中,我们添加一个 securitySchemes 对象,该对象定义了我们正在使用的安全方案的详细信息:
components:
securitySchemes:
API-Key:
type: apiKey
description: "The API authorizes requests through an API key in your header."
name: X-API-Key
in: header
和部分tags
externalDocs
想象一下,如果您有一个包含 50 多条路径的 API 需要描述。您需要将它们组织成逻辑组,以便用户导航。该tags
对象提供了一种在 Swagger UI 显示中对路径(端点)进行分组的方法。
在根级别定义您的标签:
tags:
- name: Products
description: Handles product information.
- name: Orders
description: Operations for processing purchases and orders.
然后您可以在各个操作中使用任何定义的标签:
paths:
...
/products:
get:
...
tags:
- Products
...
这将在 Swagger UI 中将具有相同标签的操作分组:
以下是一个对象的示例externalDocs
:
externalDocs:
description: Product documentation for the API
url: https://myapi.com/docs
在 Swagger UI 中,此链接与有关 API 的其他信息一起出现在 API 描述之后。
该paths
部分
在 OpenAPI 术语中,是API 公开的paths
端点(资源),例如/pets
或,而操作是用于操纵这些路径的方法,例如、或。/products/summary/
HTTP
GET
POST
DELETE
首先,让我们列出 API 的路径:
paths:
/products:
get:
/orders:
post:
每个路径对象(/products.get
, /orders.post
)都是一个操作。以下是一个完整的示例:
paths:
/products/{id}:
get:
tags:
- Products
summary: Gets a product by ID.
description: >
A detailed description of the operation.
Use markdown for rich text representation,
such as **bold**, *italic*, and [links](http://swagger.io).
operationId: getProductById
parameters:
- name: id
in: path
description: Product ID
required: true
schema:
type: integer
format: int64
responses:
'200':
description: Successful operation
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
externalDocs:
description: Learn more about product operations provided by this API.
url: http://api.example.com/docs/product-operations/
每个操作都会记录该操作的所有参数、不同类型的响应以及其他元数据。您可以在components
此处引用您在本节中定义的常见数据结构。
OpenAPI摘要
这就是你开始所需的一切!快来试试吧!
一旦编写完成,OpenAPI 规范和 Swagger 工具可以进一步推动您的 API 开发,并从长远来看节省大量时间和精力:
- 使用Swagger Codegen为您的 API 生成服务器存根。只需实现服务器逻辑,您的 API 即可上线!
- 使用 Swagger Codegen 为您的 API 生成超过 40 种语言的客户端库。
- 使用Swagger UI生成交互式 API 文档,让您的用户直接在浏览器中尝试 API 调用。
- 还有更多!
结束语
Schema-first API 设计方法主张在编写任何代码之前先使用多种 API 规范语言之一编写 API 定义。
采用模式优先的 API 设计,初始投资和学习曲线较小,但收益却十分显著。编写 API 规范可以带来诸多好处,例如改进 API 设计、加快迭代速度以及自动化代码和文档生成。
附录
如果我已经有 API 怎么办?
如果您已经实现了 API(至少是部分实现),则可以从Swagger Inspector对您的 API 进行 API 调用。
以为您调用的任何端点自动生成 OpenAPI 文件。
补充阅读
以下是一些推荐的进一步学习的资源:
文章来源:https://dev.to/yos/schema-first-api-design--41de在yos.io上查找更多有趣的文章