Skip to Content

API 结构文档

本文档介绍 Zion 项目运行时 GraphQL API 的底层结构,供开发者在 Debug 时或在外部系统、代码组件或自定义前端中调用 Zion 后端能力时参考。

Zion 的运行时 API 采用统一 GraphQL 入口。数据库读写、行为流调用、AI 智能体会话、外部 API 调用都通过 GraphQL 的 querymutationsubscription 表达,差异主要体现在根字段名称、参数和返回结构。

API 访问地址

HTTP GraphQL

项目运行时的 HTTP GraphQL 地址格式如下:

https://zion-app.functorz.com/zero/{projectExId}/api/graphql-v2

其中:

参数说明
projectExIdZion 项目的唯一标识。

HTTP 请求体采用标准 GraphQL JSON 结构:

{ "query": "mutation CreateBlog($object: blog_insert_input!) { insert_blog_one(object: $object) { id } }", "operationName": "CreateBlog", "variables": { "object": { "title": "我的第一篇博客" } } }

WebSocket Subscription

订阅地址格式如下:

wss://zion-app.functorz.com/zero/{projectExId}/api/graphql-subscription

订阅主要用于异步行为流任务、AI 智能体流式结果、数据变化监听等场景。

认证与权限

请求头中可通过 Authorization 传入 JWT:

Authorization: Bearer <jwt>

未携带 JWT 时,请求按游客身份执行。携带 JWT 后,后端会根据 JWT 解析当前账号、角色、权限,并在执行数据库、行为流、AI 智能体或外部 API 调用前进行权限校验。

JWT 可通过登录接口获取。用户名密码登录示例如下:

mutation AuthenticateWithUsername($username: String!, $password: String!, $register: Boolean!) { authenticateWithUsername(username: $username, password: $password, register: $register) { account { id permissionRoles } jwt { token } } }

其中 registertrue 时表示注册并登录,为 false 时表示直接登录。返回的 jwt.token 即可作为后续请求的 Bearer Token。

请求与响应结构

GraphQL operation 分为三类:

更多关于 GraphQL 的介绍,请参考 GraphQL 官方文档

类型用途Zion 中的典型场景
query读取数据查询数据表、查询异步任务结果、调用只读外部 API。
mutation修改数据或触发动作添加/修改/删除数据、触发行为流、创建 AI 会话、发送 AI 消息、调用外部 API。
subscription监听结果变化数据库数据变化时,实时获取最新数据。

成功响应会返回 data。如果执行中出现异常或字段权限错误,会返回 errors

{ "data": null, "errors": [ { "message": "permission denied", "path": ["insert_blog_one"] } ] }

GraphQL 只会返回请求中显式声明的字段。数据库写入类操作中,Zion 会确保 id 字段可用于后续行为引用。

数据库操作

Zion 会根据项目数据模型自动生成数据表对应的 GraphQL 字段。接下来用 Zion 自带的查询、添加、修改、删除、事务处理行为来说明 GraphQL 语法。 以下示例中bloggoodsorder 等均代表项目中的数据表名。

字段类型映射

数据表字段会映射为对应的 GraphQL 类型。常见类型如下:

Zion 数据类型GraphQL 类型说明
文本String文本。
长整数bigint长整数,常用于 id。
无限精度小数Decimal高精度小数。
布尔值Boolean布尔值。
JSONBjsonbJSON 对象。
日期时间(带时区)timestamptz日期、时间和时间间隔。
时间(带时区)timetz日期、时间和时间间隔。
日期date日期、时间和时间间隔。
经纬度geography地理位置。
图片FZ_Image图片。
视频FZ_Video视频。
文件FZ_File文件。

媒体字段在 GraphQL 入参中通常以资源 id 表达:单个图片、视频、文件字段对应 {field_name}_id,媒体数组字段对应 {field_name}_ids。例如 cover_image 字段写入时传 cover_image_id

查询数据

数据查询使用 query 类型。

常见根字段与参数

在 GraphQL 中,**“根字段”**是查询的最外层入口,它决定了你想要执行的操作类型。在 Zion 中,系统会自动将你的表名(如 blog)转化为对应的根字段。

例如,如果你想查询 blog 表的数据列表,根字段就是 blog,并且可以在括号内传入筛选和分页参数:

query { blog(where: {...}, limit: 10) { # 这里的 blog 就是查询的根字段 id title } }

根据查询需求的不同,Zion 提供了以下几种常见的根字段格式:

字段格式说明
{table_name}查询数据列表,支持 whereorder_bylimitoffset 等参数。
{table_name}_by_pk按主键查询单条数据。
{table_name}_aggregate聚合查询,返回 nodesaggregate
{table_name}_group_by分组查询,支持 group_byhavingwhereorder_bylimitoffset 等参数。
fz_{table_name}_by_{column_name}地理位置查询。当表中包含地理位置字段时,可用于按距离查询。

查询参数

当使用上述根字段(如 {table_name}{table_name}_aggregate)时,通常需要传入查询参数来控制返回的数据范围。常见的筛选、排序和分页参数如下:

参数说明
where筛选条件,类型为 {table_name}_bool_exp
order_by排序条件,支持字段排序、关联字段排序、聚合排序。
distinct_on按指定字段去重。
limit限制返回条数。
offset跳过指定条数,用于分页。

where 过滤语法

逻辑运算符:

运算符说明
_and多个条件同时满足。
_or多个条件满足任意一个。
_not对条件取反。

比较运算符:

运算符说明
_eq / _neq等于 / 不等于。
_gt / _gte大于 / 大于等于。
_lt / _lte小于 / 小于等于。
_in / _nin在集合中 / 不在集合中。
_like / _ilike文本匹配 / 忽略大小写文本匹配。
_is_null是否为空。

关联查询:

筛选条件可以沿关联字段继续嵌套。例如查询作者名称为“小明”的博客:

{ "where": { "author": { "name": { "_eq": "小明" } } } }

操作符优先:

在普通的 GraphQL 查询中,我们通常只能直接做简单的“字段 = 值”的比较(例如 age: { _gt: 18 })。但如果想使用数据库内置函数来处理字段(例如提取出时间的月份,再判断它是否等于 12),默认的 GraphQL 结构写不出来。

因此,Zion 提供了一种操作符优先的特殊语法:先写比较操作符(如等于 _eq),然后在左侧(left_operand)调用数据库函数提取字段值,在右侧(right_operand)写上你要比较的目标值。

这就等价于 SQL 中的 WHERE EXTRACT(MONTH FROM created_at) = 12

例如,查询 account 表中 created_at 月份为 12 的数据:

查询的 GraphQL 语句:

query QueryAccountList($where: account_bool_exp) { account(where: $where) { id username created_at } }

对应的 JSON 变量(Variables):

{ "where": { "_eq": { "bigint_operand": { "left_operand": { "extract_timestamptz": { "time": { "column": "created_at" }, "unit": "MONTH" } }, "right_operand": { "literal": "12" } } } } }

典型查询示例

  1. 查询列表

查询列表对应 {table_name} 根字段,通常搭配筛选、排序和分页参数使用:

查询列表示例:

query QueryBlogList($where: blog_bool_exp, $limit: Int, $offset: Int) { blog(where: $where, order_by: { id: desc }, limit: $limit, offset: $offset) { id title author_id } }

对应的 JSON 变量(Variables):

{ "where": { "_and": [ { "author_id": { "_eq": 10001 } }, { "title": { "_ilike": "%Zion%" } } ] }, "limit": 20, "offset": 0 }
  1. 按主键查询

按主键查询对应 {table_name}_by_pk 根字段,用于精确获取单条数据:

query QueryBlogByPk($id: bigint!) { blog_by_pk(id: $id) { id title content } }
  1. 聚合查询

聚合查询对应 {table_name}_aggregate 根字段,支持与查询列表相同的 where 等参数,可以同时返回数据节点(nodes)和聚合结果(aggregate):

query QueryBlogAggregate($where: blog_bool_exp) { blog_aggregate(where: $where) { nodes { id title } aggregate { count max { id } } } }

添加数据

数据添加操作使用 mutation 类型。

常见根字段与参数

单条添加组装为 insert_{table_name}_one 的 GraphQL 树,批量添加组装为 insert_{table_name}

字段格式说明
insert_{table_name}_one单条添加。
insert_{table_name}批量添加。

当使用上述根字段时,通常需要传入以下参数:

参数说明
object单条添加时传入,包含要添加的数据字段及值的 JSON 对象。
objects批量添加时传入,包含多个 object 的 JSON 数组。
on_conflict冲突处理策略,当插入的数据与已有数据主键或唯一约束冲突时的处理方式。

典型添加示例

  1. 单条添加

查询的 GraphQL 语句:

mutation($object: blog_insert_input!, $on_conflict: blog_on_conflict!) { insert_blog_one(object: $object, on_conflict: $on_conflict) { id } }

对应的 JSON 变量:

{ "object": { "title": "我的第一篇博客", "content": "这是博客的内容。", "author_id": 10001 }, "on_conflict": { "constraint": "unique_title", "update_columns": [] } }

on_conflict.update_columns 为空数组时,对应 Zion 前端“添加”行为中的“忽略并跳过”。指定全部字段数组时,对应“修改原有数据”。

  1. 批量添加

查询的 GraphQL 语句:

mutation( $objects: [blog_insert_input!]!, $on_conflict: blog_on_conflict! ) { insert_blog( objects: $objects, on_conflict: $on_conflict ) { returning { id } } }

对应的 JSON 变量:

{ "objects": [ { "title": "我的第一篇博客", "content": "这是第一篇博客的内容。", "author_id": 10001 }, { "title": "第二篇博客", "content": "更多精彩内容敬请期待。", "author_id": 10001 } ], "on_conflict": { "constraint": "unique_title", "update_columns": ["title", "content", "author_id"] } }

修改数据

数据修改操作使用 mutation 类型。

常见根字段与参数

修改数据对应以下两种常见的根字段格式:

字段格式说明
update_{table_name}批量修改,根据条件修改多条数据。
update_{table_name}_by_pk按主键修改单条数据。

当使用上述根字段时,通常需要传入以下参数:

参数说明
where批量修改时传入,筛选要修改的数据条件,类型为 {table_name}_bool_exp
pk_columns按主键修改时传入,包含主键字段的对象。
_set用于直接设置字段的新值。
_inc用于对数值类型字段进行原子增减操作。

典型修改示例

  1. 批量修改

以下是以商品库存扣减 2 件且限制 库存数 >= 2 为例:

查询的 GraphQL 语句:

mutation update_goods( $where: goods_bool_exp!, $inc: goods_inc_input ) { update_goods( where: $where, _inc: $inc ) { returning { id stock } } }

对应的 JSON 变量(Variables):

{ "where": { "_and": [ { "id": { "_eq": 10001 } }, { "stock": { "_gte": 2 } } ] }, "inc": { "stock": -2 } }
  1. 按主键修改

按主键修改时,使用 update_{table_name}_by_pk

查询的 GraphQL 语句:

mutation UpdateGoodsByPk($pk_columns: goods_pk_columns_input!, $set: goods_set_input) { update_goods_by_pk(pk_columns: $pk_columns, _set: $set) { id name } }

对应的 JSON 变量(Variables):

{ "pk_columns": { "id": 10001 }, "set": { "name": "新商品名称", "stock": 100 } }

删除数据

数据删除操作使用 mutation 类型。Zion 的“删除”行为会将获取到的参数组装成带有 where 过滤参数的 GraphQL 报文。

常见根字段与参数

删除数据对应以下两种常见的根字段格式:

字段格式说明
delete_{table_name}批量删除,根据条件删除多条数据。
delete_{table_name}_by_pk按主键删除单条数据。

当使用上述根字段时,通常需要传入以下参数:

参数说明
where批量删除时传入,筛选要删除的数据条件,类型为 {table_name}_bool_exp
id按主键删除时传入,主键的值。

典型删除示例

  1. 批量删除

查询的 GraphQL 语句:

mutation($where: order_bool_exp!) { delete_order(where: $where) { returning { id } } }

对应的 JSON 变量(Variables):

{ "where": { "_and": [ { "id": { "_eq": 1 } }, { "user_id": { "_eq": 1000000000000001 } } ] } }
  1. 按主键删除

按主键删除时,使用 delete_{table_name}_by_pk

查询的 GraphQL 语句:

mutation DeleteOrderByPk($id: bigint!) { delete_order_by_pk(id: $id) { id } }

对应的 JSON 变量(Variables):

{ "id": 10001 }

事务处理

Zion 的“事务处理”行为会将所有添加、修改或删除子行为统一拼接在同一个请求中发出。以下是以提交订单并扣减商品库存为例:

事务处理的 GraphQL 语句:

mutation( $objects_order: [order_insert_input!]!, $on_conflict_order: order_on_conflict!, $where_product: product_bool_exp!, $inc_product: product_inc_input! ) { # 步骤 1:添加订单 step1_insert: insert_order( objects: $objects_order, on_conflict: $on_conflict_order ) { returning { id } } # 步骤 2:修改商品库存 step2_update: update_product( where: $where_product, _inc: $inc_product ) { returning { id } } }

对应的 JSON 变量(Variables):

{ "objects_order": [{ "user_id": 10001, "amount": 99.0, "product_id": 20001 }], "on_conflict_order": { "constraint": "", "update_columns": [] }, "where_product": { "_and": [ { "id": { "_eq": 20001 } }, { "stock": { "_gte": 1 } } ] }, "inc_product": { "stock": -1 } }

同一个 mutation 中可以放入多个根字段,并通过别名(如 step1_insertstep2_update)区分返回结果。数据库写入会在后端事务中执行;如果某一步失败,事务内的数据库变更会回滚。

行为流调用

行为流适合封装多步骤后端逻辑。Zion 运行时提供同步和异步两类行为流调用方式,主要使用 mutation 触发动作,使用 querysubscription 获取异步结果。

常见根字段与参数

行为流调用对应以下几种常见的根字段格式:

字段格式类型说明
fz_invoke_action_flowmutation同步调用指定版本的行为流,并在同一次请求返回输出。
fz_invoke_action_flow_default_by_latest_versionmutation同步调用默认或最新版本的行为流。
fz_create_action_flow_taskmutation异步创建行为流任务,返回任务 id。
fz_listen_action_flow_resultsubscription监听异步行为流任务的状态和输出。
fz_action_flow_resultquery主动查询异步行为流任务的当前结果。

当使用上述根字段时,通常需要传入以下参数:

参数说明
actionFlowId行为流的唯一标识。
versionId行为流的版本号。在调用最新版本时可为空。
args传入行为流的入参,JSON 格式。
taskId异步行为流任务的 id。

典型调用示例

同步调用

同步行为流通过 fz_invoke_action_flow 调用,并在同一次 HTTP 请求中返回行为流输出。

查询的 GraphQL 语句:

mutation InvokeActionFlow($actionFlowId: String!, $versionId: Int!, $args: Json!) { fz_invoke_action_flow(actionFlowId: $actionFlowId, versionId: $versionId, args: $args) }

对应的 JSON 变量(Variables):

{ "actionFlowId": "d3ea4f95-5d34-46e1-b940-91c4028caff5", "versionId": 3, "args": { "order_id": 10001, "amount": 99 } }

同步调用也支持使用 fz_invoke_action_flow_default_by_latest_version。该字段允许 versionId 为空,由运行时使用默认或最新版本:

mutation InvokeLatestActionFlow($actionFlowId: String!, $versionId: Int, $args: Json!) { fz_invoke_action_flow_default_by_latest_version( actionFlowId: $actionFlowId, versionId: $versionId, args: $args ) }

对应的 JSON 变量(Variables):

{ "actionFlowId": "d3ea4f95-5d34-46e1-b940-91c4028caff5", "args": { "order_id": 10001, "amount": 99 } }

异步调用

异步行为流先通过 fz_create_action_flow_task 创建任务,返回任务 id:

创建任务的 GraphQL 语句:

mutation CreateActionFlowTask($actionFlowId: String!, $versionId: Int, $args: Json!) { fz_create_action_flow_task(actionFlowId: $actionFlowId, versionId: $versionId, args: $args) }

对应的 JSON 变量(Variables):

{ "actionFlowId": "d3ea4f95-5d34-46e1-b940-91c4028caff5", "versionId": 3, "args": { "order_id": 10001, "amount": 99 } }

返回示例:

{ "data": { "fz_create_action_flow_task": 1020000000000001 } }

随后通过 Subscription 监听任务结果:

监听结果的 GraphQL 语句:

subscription ListenActionFlowTask($taskId: Long!) { fz_listen_action_flow_result(taskId: $taskId) { status output } }

对应的 JSON 变量(Variables):

{ "taskId": 1020000000000001 }

也可以通过 Query 主动查询任务当前结果:

查询结果的 GraphQL 语句:

query QueryActionFlowResult($taskId: Long!) { fz_action_flow_result(taskId: $taskId) { status output } }

对应的 JSON 变量(Variables):

{ "taskId": 1020000000000001 }

行为流任务结果的 outputstatus 结构如下:

字段类型说明
statusTaskStatus任务状态。常见值包括 CREATEDPROCESSINGCOMPLETEDFAILEDSTREAMINGTIME_OUT
outputJson行为流输出节点返回的数据。

AI 智能体调用

Zion AI 智能体使用 mutation 触发调用,使用 subscription 获取结果。

AI 智能体的输入参数来自智能体配置。文本、数字等普通参数直接按参数名传入;图片、视频、文件等媒体参数需要传资源 id,并在参数名后追加 _id。如果输入是媒体数组,也使用 _ids 后缀并传入 id 数组。例如智能体配置中有一个视频输入 video,调用时应传 video_id: 1030000000000002

常见根字段与参数

AI 智能体调用对应以下几种常见的根字段格式:

字段格式类型说明
fz_zai_create_conversationmutation创建智能体会话,返回会话 id。
fz_zai_listen_conversation_resultsubscription监听智能体会话的流式或最终结果。
fz_zai_send_ai_messagemutation继续会话,向已有会话发送新消息,返回消息 id。
fz_zai_stop_respondingmutation停止当前会话中 AI 的响应。
fz_zai_delete_conversationmutation删除指定的会话。

当使用上述根字段时,通常需要传入以下参数:

参数说明
inputArgs一次性任务的提示词或创建会话时的初始入参映射。
zaiConfigId智能体配置的唯一标识。
conversationId会话 ID。
text / imageIds / fileId / videoId继续会话时,发送新消息的文本和多媒体资源。

典型调用示例

创建并监听会话

创建会话的 GraphQL 语句:

mutation ZAICreateConversation($inputArgs: Map_String_ObjectScalar!, $zaiConfigId: String!) { fz_zai_create_conversation(inputArgs: $inputArgs, zaiConfigId: $zaiConfigId) }

对应的 JSON 变量(Variables):

{ "zaiConfigId": "zai_01HZXEXAMPLE", "inputArgs": { "question": "请总结这篇文章", "article_id": 10001, "cover_image_id": 1020000000000097 } }

创建会话后,通过 Subscription 监听流式或最终结果:

监听会话的 GraphQL 语句:

subscription ListenZAIConversation($conversationId: Long!) { fz_zai_listen_conversation_result(conversationId: $conversationId) { conversationId status data reasoningContent images { id url } } }

对应的 JSON 变量(Variables):

{ "conversationId": 1 }

流式输出说明:流式文本输出会多次推送 STREAMING 状态,最后一次 COMPLETED 状态中的 data 会包含汇总后的完整输出。结构化输出不会流式返回,最终 COMPLETED 消息中的 data 会是符合智能体结构化对象。图片输出模型会在 images 字段中返回生成图片的资源对象。

会话消息管理

多轮对话中,可以向已有会话发送新消息、停止响应或删除会话。

发送新消息的 GraphQL 语句:

mutation ZAISendAiMessage( $conversationId: Long!, $text: String, $imageIds: [Long], $fileId: Long, $videoId: Long ) { fz_zai_send_ai_message( conversationId: $conversationId, text: $text, imageIds: $imageIds, fileId: $fileId, videoId: $videoId ) }

对应的 JSON 变量(Variables):

{ "conversationId": 1, "text": "这段代码有点问题,请帮忙看看。", "imageIds": [1020000000000097] }

(发送后继续订阅同一个 conversationId 即可获得后续结果)

停止响应的 GraphQL 语句:

mutation StopZAIResponding($conversationId: Long!) { fz_zai_stop_responding(conversationId: $conversationId) }

对应的 JSON 变量(Variables):

{ "conversationId": 1 }

删除会话的 GraphQL 语句:

mutation DeleteZAIConversation($conversationId: Long!) { fz_zai_delete_conversation(conversationId: $conversationId) }

对应的 JSON 变量(Variables):

{ "conversationId": 1 }

外部 API 调用

Zion 支持在项目中配置外部 API,并将其暴露为 GraphQL 字段。外部 API 可以作为 querymutation 调用,取决于该 API 在 Zion 中的类型配置。

常见根字段与参数

外部 API 有两套命名形式及对应的根字段格式:

字段格式说明
operation_{thirdPartyApiId}旧版第三方 API,以导入的 OpenAPI operation id 生成 GraphQL 字段。
fz_api_{apiId}新版 API Workspace,以 API Workspace 中的 API 标识生成 GraphQL 字段。

当使用上述根字段时,通常需要传入相应的请求参数:

参数说明
fz_body旧版第三方 API 的请求体参数,通常为 JSON 结构。
Authorization旧版第三方 API 的请求鉴权头。其他路径或查询参数也会按 API 配置生成为 GraphQL 参数。
input新版 API Workspace 的请求参数,类型通常为 fz_api_{api_name}_input

提示:当外部 API 被配置在行为流节点中时,外部调用不会单独暴露给前端,而是作为行为流执行过程的一部分。此时前端调用的是行为流相关字段。如果外部 API 返回非 2xx 状态码,行为流会将该节点视为执行失败。

典型调用示例

1. 旧版第三方 API

旧版第三方 API 调用后应先检查 responseCode,当外部 API 返回 4xx 或 5xx 时,field_200_json 可能为空。

查询的 GraphQL 语句:

mutation CreateCalendarEvent( $summary: String, $location: String, $authorization: String ) { operation_create_calendar_event( fz_body: { summary: $summary, location: $location }, Authorization: $authorization ) { responseCode field_200_json { id status htmlLink } } }

对应的 JSON 变量(Variables):

{ "summary": "项目周会", "location": "会议室 A", "authorization": "Bearer third_party_token" }

2. 新版 API Workspace

新版 API Workspace 的响应通常包含了 HTTP 状态码、内容类型以及对应配置好的结构化响应字段。

查询的 GraphQL 语句:

mutation CallApi($input: fz_api_create_order_input!) { fz_api_create_order(input: $input) { responseCode responseStatus responseContentType fz_api_create_order_response { order_id status } } }

对应的 JSON 变量(Variables):

{ "input": { "order_id": 10001, "amount": 99.0 } }
Last updated on