统一 API:跨服务 API 的共享契约
统一 API 为调用方提供一套覆盖多个服务 API 的共享契约。各数据源专用的适配器在这套契约与对应服务的接口之间转换请求、记录和失败信息。统一的数据结构减少了调用方需要了解的细节,但支持哪些操作、字段具有何种含义,仍取决于底层服务。
作者:Ai Flowi · 发布于
什么让契约实现统一?
调用方使用约定的字段名称和含义,请求人员记录等通用资源。每个数据源的适配器负责处理其特有的数据结构。这样,调用方就能用相同的逻辑展示这些记录,而无法安全转换的差异仍由适配器负责处理。
调用一个端点属于普通的 API 集成。工作流运行端点对外提供工作流的输入和输出,操作目录则列出可用操作。它们本身都不构成跨服务的共享记录契约。区别在于语义:把两个字段都重命名为 state,并不会让它们的含义变得相同。
两套虚构数据结构,一套记录契约
以下记录明确为虚构的只读示例。数据源 A 将 active 定义为布尔值。数据源 B 将 status 定义为文本:enabled 和 disabled 是已知值,其他字符串对这个适配器而言仍属于未知值。这些记录描述的是不同人员,不表示它们已完成身份匹配。
{"id":"A-17","full_name":"Mira Chen","active":true}
{"record_key":"B-42","given_name":"Jon","family_name":"Rao","status":"paused"}
定义三个标准字段。source_id 保存数据源标签和原样保留的标识符。display_name 保存展示用文本,绝不充当身份键。state 保存标准化值、原始值和字段存在标记。保留原始状态,可以让信息损失显现出来。
在窄屏上,可将焦点移到表格并横向滚动。
| 标准字段 | 数据源 A | 数据源 B | 边界规则 |
|---|---|---|---|
source_id | 数据源 A 标签加 id | 数据源 B 标签加 record_key | 保留原始字符串,包括前导零。拒绝缺失、值为 null 或空白的标识符。 |
display_name | 去掉 full_name 首尾空白 | 去掉已有文本姓名部分的首尾空白,并以空格连接 | 没有非空白文本时返回 null。不要猜测缺失的姓名,也不要拆分 A 的全名。 |
state.normalized | true → active;false → inactive | enabled → active;disabled → inactive | 字段存在但值无法识别 → unknown。明确为 null 或字段缺失 → null。 |
state.raw 和 state.present | 原始 active 值,以及该键是否存在 | 原始 status 值,以及该键是否存在 | 原样保留陌生值。raw 为 null 且 present 为 true,与 raw 为 null 且 present 为 false 不同。 |
以下为预期的标准记录。B 的 paused 保留为未知状态;将它解释为非活跃状态,就等于添加了一条虚构数据源未提供的业务规则。
{
"source_id":{"source":"A","id":"A-17"},
"display_name":"Mira Chen",
"state":{"normalized":"active","raw":true,"present":true}
}
{
"source_id":{"source":"B","id":"B-42"},
"display_name":"Jon Rao",
"state":{"normalized":"unknown","raw":"paused","present":true}
}
如果 A 提供 active:null,状态就是 {"normalized":null,"raw":null,"present":true}。如果 A 省略 active,只有 present 变为 false。两者都不会变成非活跃状态。姓名字段类型无效时,需要复核,不能自动转换为文本。
用能力矩阵避免误判能力等同
假设这些虚构服务具有以下能力。这些是示例的设计假设,不是提供商已记录的功能。共享 API 必须在公布记录结构的同时,公布其操作覆盖范围。
| 操作 | 数据源 A | 数据源 B | 共享契约 |
|---|---|---|---|
| 按 ID 读取人员 | 支持 | 支持 | 支持,但 ID 必须包含数据源信息 |
| 列出人员 | 页码 | 不透明游标 | 需要各自的续查适配器 |
| 停用人员 | 支持写入 | 无写入操作 | 不纳入共同操作 |
| 单独读取姓氏 | 不可用 | 可用 | 不纳入标准记录 |
这就是取共同能力交集时的取舍。只读人员目录视图可以使用两个数据源。如果调用方必须能停用每一位人员,就无法使用这套共同契约:修改 B 在本地的标准化状态,并不会执行远程写入。数据源专用扩展可以提供更丰富的操作,但使用这些扩展的调用方必须了解该数据源。
适配器必须按数据源分别处理哪些事项?
- 凭据归属。 API 集成指南介绍单个连接的身份认证。对于这个目录,应使用你自己的 A、B 提供商账户和凭据,并分别向各提供商付费。将每个连接与其数据源标签关联:获准读取 A-17,不代表获准读取 B-42。如果 B 的访问权限被撤销,应显示 B 不可用,不能悄悄把 A 的记录当作完整目录展示。
- 无法映射的字段。 展示用的全名无法可靠地拆成名和姓。应排除这项能力,或提供有文档说明的数据源专用扩展。不要用推断出的个人数据填补缺口。
- 分页。 合并目录需要两个独立位置:A 的下一页和 B 的下一个游标。A 完成并不代表 B 完成。将续查信息绑定到所请求的数据源集合,使为单独查询 A 生成的值不能用于继续查询 A 加 B 的列表。如果某个数据源中途失败,应标明未完成的部分;单一的全局页码会掩盖这种区别。
- 保留错误信息。 不受支持的停用 B-42 请求,与被拒绝的读取 B-42 请求,需要不同的结果:前者超出了公布的能力范围,后者则是允许的操作执行失败。返回数据源标签和安全的诊断代码,不泄露其凭据或人员数据。B 的查找失败后,即便两者的展示姓名恰好相同,也不能用 A-17 代替。
- 数据结构版本。 假设 B 添加
suspended,但未定义它是非活跃还是暂时不可用。在当前适配器版本下,应将它保留为未知状态。修改映射前,先记录修订后的含义,并针对同一个 B 测试样本比较新旧标准记录。调用方可能根据标准化状态隐藏记录,因此,即便所有字段名称都没变,适配器更新仍可能改变目录。
在 AI Flowi Workflow 中如何体现?
示例配置,并非有记录的测试
组件目录提供了可用于演示适配器的基础组件。这些接口用途已在组件目录中说明;Ai Flowi 未对这个双数据源示例进行生产环境测试。它们并不构成托管的统一 API 服务。
每个数据源读取请求的 HTTP 配置,请参阅 API Request 参考文档。发送查找请求前,根据 source_id.source 决定调用哪个适配器:A 使用原始 id,B 使用 record_key。绝不能根据标识符的写法推断数据源。两者都可能分配标识符 0007;调用方选择 B 的 0007 时,如果却请求 A 的 0007,即便响应格式正确,也会返回错误的人员。构建共享记录前,应检查返回的标识符是否与请求中包含数据源信息的身份一致。
JSON Operations 参考文档介绍导出的 Rename Keys
、Select Keys
和 JQ Expression
选项。对于 A,将标签 active 改成 state 后,值仍是布尔值,而本契约要求结构化值。对于 B,如果只选择熟悉的 enabled 和 disabled 值,就会丢弃示例中的 paused 证据。移除数据源字段前,先保存原始状态和键的存在情况,再应用已声明的值映射。使用 B 现有的姓名部分构建展示姓名;A 的全名保持不拆分。
对象组装请参阅 JSON Object Builder,分支配置请参阅 Condition。对于本契约,组装出的记录必须将 source_id 保留为对象,不能展平为 ID 字符串。比较具有相同字面 ID 的 A、B 记录,确认它们仍有区别。还应比较字段存在但值为 null 的状态与字段缺失的状态:两者都需要保留 raw:null,但 present 标记不同。丢弃 null 字段或将嵌套状态转成文本,都不符合本契约,无论编辑器是否接受该连接。
如果目录要把活跃人员与其他人员分开,应规定三种结果:活跃、非活跃和待确认。B 的 paused 属于待确认,其原始值应保留供诊断使用。A 的 false 布尔值属于非活跃,而字段缺失和明确为 null 的状态都保持待确认,并保留不同的存在标记。仅仅未通过活跃状态比较的分支,不能据此认定为非活跃。使用组件输出前,应将每条结果记录完整的 source_id 和 state 与这些预期逐一比较;这里展示的示例定义的是验收标准,不是已记录的路由结果。
工作流 API 指南介绍如何对外提供工作流运行接口。即便发布了这样的端点,这套共享数据结构、操作覆盖范围和适配器维护仍由你负责。
套餐:Go 年付方案每月 USD8 起(月付 USD10),Plus 年付方案每月 USD16 起(月付 USD20),Pro 100 年付方案每月 USD80 起(月付 USD100),Pro 200 年付方案每月 USD160 起(月付 USD200),Pro 500 年付方案每月 USD400 起(月付 USD500),每月包含 5,000 至 250,000 个 Flowi Tokens,并支持充值;每次节点运行消耗 1 个 token;不包含第三方 API 和模型使用费用。
常见错误与不宜统一的情况
不要因为展示姓名相同就合并人员,不要把未知状态变成 false,也不要仅因一个适配器支持写入就宣称共同接口支持写入。针对已知、未知、null 和缺失状态测试每个适配器。如果任务依赖共享契约无法表达的数据源专用字段或操作,应选择直接集成该数据源。只有调用方能接受已声明的信息损失,统一的只读视图才有用。