规范优先的设计与模拟
导入或设计 OpenAPI 规范,对其进行 lint,提供它的模拟服务,向模拟服务器发送请求,并对照规范检查真实响应。
规范优先意味着 OpenAPI 文档先于代码:先约定好 API,用模拟服务器试用它,等真实服务器出现后再对照同一份文档检查。在本教程中,你会把 Alpenglow 商店的规范添加到工作区,设计一个商店尚不具备的端点,在 Mac 上用模拟服务器同时提供两者,并对照规范检查真实 API 的响应。
- 用时: 20 分钟。
- 你需要: Echolot 和一个工作区,比如你的第一个工作区中的那个,或者一个新的空工作区。
- 你将学到: “规范”页面、lint、遵循规范的请求、模拟服务器,以及 OpenAPI 规范检查。
1. 添加规范
演示商店在 https://demo.echolot.dev/openapi.yaml 发布了它的规范。
-
把它存到你的 Mac 上。在“终端”中:
curl -o ~/Downloads/openapi.yaml https://demo.echolot.dev/openapi.yaml或者在 Safari 中打开该地址,然后选取文件 › 存储为…。
-
在工作区窗口中切换到规范(⌘3)。
-
选取添加规范文件…(在空白页面上,或边栏的 + 菜单中),然后选择
openapi.yaml。副本会放入工作区的specs文件夹。
规范会在可视化编辑器中打开:它的服务器、按路径或标签分组的端点,以及它的 Schema。工具栏上的开关可在可视化和代码之间切换。两者编辑的是同一份文本,存储的也是这份文本。
从零开始
请改为选取新建规范。你会得到一份标题为新 API 的 OpenAPI 3.1 文档,其中有一个端点 GET /items,可供重命名和扩展。本教程的其余部分操作方式相同。
2. 设计商店尚不具备的端点
商店想要一个门店列表。在有人动手实现之前,先把它设计出来。
-
在可视化编辑器中选取添加端点。
-
在新建端点中,保持方法为 GET,输入路径
/stores、摘要List stores和标签Catalog。选取添加端点。Echolot 会添加该操作,并附带一个200响应作为起点。 -
在端点的编辑器中,把操作 ID 设为
listStores。 -
选取在代码中显示。把端点的
responses替换为带有正文和示例的版本:responses: '200': description: The shop's stores. content: application/json: schema: type: array items: type: object required: [id, city] properties: id: { type: string } city: { type: string } address: { type: string } example: - { id: zrh, city: Zürich, address: Bahnhofstrasse 1 } - { id: brn, city: Bern, address: Spitalgasse 4 }
编辑会随着你的操作自动存储,⌘Z 可撤销。可视化编辑只会改动你所碰触条目的那几行,因此文件的其余部分(包括注释)保持你写下的样子。详见编辑规范。

3. 对规范进行 lint
工具栏上的问题按钮会显示绿色对勾和没有问题,或者错误和警告的数量。
- 选取它。问题弹出窗口会说明文档符合 OpenAPI 规范,且所有引用都能解析。
- 制造一个问题来看看:在代码中,把某一行的
$ref: '#/components/schemas/Product'改成'#/components/schemas/Produkt'。按钮会变红。选取它并选中该问题:编辑器会跳到对应的行。 - 撤销这个更改(⌘Z)。
同样的 lint 也可以通过命令行工具在 CI 中运行。--strict 会在出现警告时同样失败,--hints 会加入建议,例如缺少操作 ID:
echolot spec lint specs/openapi.yaml --strict4. 创建遵循规范的请求
- 在“规范”工具栏中选取生成请求。请求下会出现一个文件夹 Alpenglow demo shop,其中每个标签一个文件夹(Catalog、Auth、Orders),每个端点一个请求,包括 List stores。
- 查看 Catalog › List products。它的 URL 是
{{baseUrl}}/products。它的测试标签页已经带有规范生成的两项检查:状态等于200,以及所记录正文的 JSON Schema。
这个文件夹会跟随规范。之后规范有变化时,“规范”工具栏的请求菜单会提供检查“Alpenglow demo shop”的更改…:它列出规范中新增、更改和删除的内容,并在不覆盖你对请求所做编辑的前提下应用它们。参见 OpenAPI 同步。
生成的请求以 {{baseUrl}}(小写的 rl)开头。你会在接下来的两个步骤中给它赋值。
5. 提供规范的模拟服务
- 切换到模拟服务器(⌘4)。打开 + 菜单并选取 Alpenglow demo shop 的模拟服务器。
- 选取开始(⌘R)。工具栏会显示绿点和地址
http://127.0.0.1:4010/v1:从 4010 起的第一个空闲端口,以及来自规范服务器的基础路径。 - 选取在环境中使用。Echolot 会创建一个环境 Mock: Alpenglow demo shop,其
{{baseUrl}}就是模拟服务器的地址,并选中它。
设置卡片中有模拟服务器的端口、应答网络上的其他设备、每次应答前的延迟、一定比例的失败率(注入的 500 响应),以及检查:拒绝违反规范的请求(返回 400 及原因)。模拟服务器在窗口打开期间运行。

6. 向模拟服务器发送请求
- 回到请求,发送 Catalog › List stores。模拟服务器返回
200和你示例中的两家门店。标头标签页显示Server: Echolot mock。 - 发送 Catalog › List products。模拟服务器没有它的示例,所以会根据 Schema 生成一个正文:形状正确,值是占位符。请求的两项检查都通过。
- 在 List products 的参数中,添加
sort,值为cheapest,然后发送。模拟服务器会拒绝它:返回400和query “sort”: not one of the allowed values。规范允许name、price、-price和rating。移除这个参数。 - 在 Get a product 中添加标头
Prefer: code=404并发送。模拟服务器会改为返回规范中记录的404问题响应。移除这个标头。
“模拟服务器”页面的日志列出了模拟服务器应答的每个请求,包括匹配到的操作和任何问题。在响应卡片中,你可以让某个操作对每个请求都返回另一个已记录的状态或示例。需要状态的应答可以使用 JavaScript 路由,参见脚本路由。
7. 对照规范检查真实 API
- 在环境页面添加环境
Demo,其中变量baseUrl设为https://demo.echolot.dev/v1,然后在页面标题栏中选择它。 - 打开 List products,在它的测试标签页中打开添加测试并选取 OpenAPI 规范。它没有需要填写的内容:它会按规范为返回的状态记录的 Schema 来检查正文。
- 发送。三项检查全部通过:真实的商店与它的规范一致。
- 发送 List stores。真实的商店返回
404:这个端点只存在于规范中。这正是规范优先的意义:模拟服务器让你现在就能基于它开发。
要在 CI 中运行同样的检查,请用 echolot run 运行该文件夹,并在那里用 echolot mock 提供模拟服务:
echolot mock specs/openapi.yaml --port 4010后续步骤
- 从流量生成规范:根据你已经发送的请求编写规范。
- 模拟服务器:从历史记录存储的示例、延迟、失败,以及在网络上共享。
echolot spec:文件夹落后于其规范时,check会让 CI 失败。

