Runtime API 参考
Zion 会为每个项目生成 Runtime GraphQL API。你可以通过它在自定义前端、服务端程序或其他系统中访问项目数据库,并调用行为流、AI 智能体和第三方 API。
项目的数据模型和功能配置会共同决定最终的 GraphQL Schema。本文说明稳定的调用方式和字段命名规则;具体项目中可用的字段、参数和返回类型,请以 开发者接入 中的 GraphiQL 为准。
开始使用
在编辑器中打开 开发者接入,可以复制以下项目专属信息:
- GraphQL 接口地址:发送 Query 和 Mutation。
- GraphQL 订阅地址:建立 Subscription 连接。
- Admin Bearer Token:以项目管理员权限访问后端。
- GraphiQL:查看当前项目的 Schema,并直接调试请求。
接口地址的格式如下:
https://zion-app.functorz.com/zero/{projectExId}/api/graphql-v2
wss://zion-app.functorz.com/zero/{projectExId}/api/graphql-subscription数据模型、行为流入参或出参、AI 智能体和第三方 API 发生变化后,需要先同步变更或发布,再刷新 GraphiQL Schema。
HTTP 请求
Query 和 Mutation 使用标准 GraphQL JSON 请求体:
{
"query": "query GetPosts($limit: Int!) { post(limit: $limit) { id title } }",
"operationName": "GetPosts",
"variables": {
"limit": 10
}
}认证
Runtime API 根据请求携带的身份执行权限校验。
| 身份 | 认证方式 | 适用场景 |
|---|---|---|
| 游客 | 不发送 Authorization | 访问允许游客使用的数据和功能。 |
| 当前用户 | Authorization: Bearer <jwt> | 按登录用户的角色和权限执行请求。 |
| 项目管理员 | Authorization: Bearer <admin_token> | 可信服务端、脚本或本地开发环境中的后台管理操作。 |
Admin Bearer Token 拥有项目级高权限。不要把它写入网页、客户端应用、公开仓库或任何会发送给终端用户的代码。
获取用户 JWT
不同登录方式会生成不同的认证字段。以下示例使用用户名和密码获取 JWT:
mutation AuthenticateWithUsername(
$username: String!
$password: String!
$register: Boolean!
) {
authenticateWithUsername(
username: $username
password: $password
register: $register
) {
account {
id
permissionRoles
}
jwt {
token
}
}
}register: true 表示注册并登录,register: false 表示登录已有账号。将返回的 jwt.token 放入后续 HTTP 请求头:
Authorization: Bearer <jwt>认证 Subscription
Subscription 使用 graphql-ws 协议。建立连接时,在 connection_init 消息的 payload 中传入 Token:
{
"type": "connection_init",
"payload": {
"authToken": "<jwt_or_admin_token>"
}
}请求、响应与错误
Runtime API 支持三类 GraphQL Operation:
| 类型 | 用途 | 常见场景 |
|---|---|---|
query | 读取数据 | 查询数据表、查询异步任务结果、获取上传地址。 |
mutation | 修改数据或触发执行 | 添加、修改、删除数据,调用行为流或 AI 智能体。 |
subscription | 持续监听结果 | 监听异步行为流、AI 智能体或数据变化。 |
GraphQL 只返回 Operation 中显式选择的字段。成功响应通常包含 data:
{
"data": {
"post": [{ "id": 1, "title": "Hello" }]
}
}执行失败时,响应包含 errors。GraphQL 也可能同时返回部分 data 和 errors,调用方应分别处理:
{
"data": null,
"errors": [
{
"message": "permission denied",
"path": ["post"]
}
]
}排查错误时,优先检查 message、path 和响应中的请求标识,再到运行日志中定位对应请求。
接口参考
数据库
Zion 根据数据模型生成表查询、关联查询、聚合和写入字段。以下示例使用 post 表;请在 GraphiQL 中替换为项目的实际表名和字段。
数据类型
| Zion 数据类型 | GraphQL 类型 | 说明 |
|---|---|---|
| 文本 | String | 文本值。 |
| 长整数 | bigint 或生成的长整数类型 | 常用于数据 id;以 Schema 中的实际类型为准。 |
| 无限精度小数 | Decimal | 高精度小数。 |
| 布尔值 | Boolean | true 或 false。 |
| JSONB | jsonb | JSON 数据。 |
| 日期时间(带时区) | timestamptz | 包含日期、时间和时区的时间点。 |
| 时间(带时区) | timetz | 包含时区的时间。 |
| 日期 | date | 不包含时间的日期。 |
| 经纬度 | geography | 地理位置。 |
| 图片 | FZ_Image | 图片资源。 |
| 视频 | FZ_Video | 视频资源。 |
| 文件 | FZ_File | 文件资源。 |
写入媒体字段时,单个资源通常使用 {field_name}_id,资源数组使用 {field_name}_ids。例如,图片字段 cover 对应入参 cover_id。
查询数据
常见查询字段如下。部分字段只会在对应功能或字段类型存在时生成。
| 字段格式 | 说明 |
|---|---|
{table_name} | 查询列表,支持筛选、排序和分页。 |
{table_name}_by_pk | 按主键查询单条数据。 |
{table_name}_aggregate | 查询数量、合计等聚合结果。 |
{table_name}_group_by | 分组查询。 |
fz_{table_name}_by_{column_name} | 按地理位置字段执行距离查询。 |
列表查询常用参数包括:
| 参数 | 说明 |
|---|---|
where | 筛选条件,类型通常为 {table_name}_bool_exp。 |
order_by | 排序条件。 |
distinct_on | 按指定字段去重。 |
limit | 返回条数上限。 |
offset | 跳过指定条数。 |
常用比较操作符包括 _eq、_neq、_gt、_gte、_lt、_lte、_in、_nin、_like、_ilike 和 _is_null;使用 _and、_or、_not 组合条件。
query GetPublishedPosts($where: post_bool_exp!, $limit: Int!) {
post(
where: $where
order_by: { created_at: desc }
limit: $limit
) {
id
title
author {
id
name
}
}
}{
"where": {
"status": { "_eq": "published" },
"author": { "name": { "_ilike": "%明%" } }
},
"limit": 20
}操作符优先筛选
需要先对字段执行数据库函数再比较结果时,可以使用操作符优先筛选。例如,判断 created_at 的月份是否为 12:
{
"where": {
"_eq": {
"left_operand": {
"extract": {
"field": "created_at",
"part": "MONTH"
}
},
"right_operand": 12
}
}
}可用函数和入参由字段类型及当前 Schema 决定,请在 GraphiQL 中查看对应的输入类型。
添加数据
mutation CreatePost($object: post_insert_input!) {
insert_post_one(object: $object) {
id
title
created_at
}
}{
"object": {
"title": "My first post",
"status": "draft",
"cover_id": 1020000000000097
}
}批量添加使用 insert_{table_name},入参通常为 objects,并返回 affected_rows 和所选择的 returning 字段。
修改数据
mutation PublishPost($id: bigint!, $set: post_set_input!) {
update_post_by_pk(pk_columns: { id: $id }, _set: $set) {
id
status
}
}{
"id": 100000000000001,
"set": { "status": "published" }
}批量修改使用 update_{table_name},通过 where 选择记录,并通过 _set、_inc 等参数指定变更。
删除数据
mutation DeletePost($id: bigint!) {
delete_post_by_pk(id: $id) {
id
}
}批量删除使用 delete_{table_name}(where: ...)。删除前应确认表关联和删除规则,避免级联影响其他数据。
事务
在同一个 Mutation 中依次声明多个数据库写入字段,可以整批原子执行:全部成功时提交,任一数据库操作失败时整体回滚。
mutation CreateOrder($order: order_insert_input!, $items: [order_item_insert_input!]!) {
insert_order_one(object: $order) {
id
}
insert_order_item(objects: $items) {
affected_rows
}
}事务保证只覆盖这次 Mutation 中的数据库写入。外部 HTTP 请求、AI 智能体或行为流产生的外部副作用不属于该数据库事务。
行为流
行为流入参和出参由项目配置决定。同步变更或发布后,在 GraphiQL 中确认当前字段和类型。当前接口会调用已部署的行为流,不需要指定版本。
| 字段 | 类型 | 说明 |
|---|---|---|
fz_invoke_action_flow_default_by_latest_version | mutation | 同步调用行为流并返回输出。 |
fz_create_action_flow_task | mutation | 创建异步任务并返回任务 id。 |
fz_listen_action_flow_result | subscription | 监听异步任务结果。 |
fz_action_flow_result | query | 主动查询异步任务结果。 |
Schema 中的 versionId 参数和 fz_invoke_action_flow 字段仅用于兼容早期已经接入的调用。新调用不要传入行为流版本。
同步调用
mutation InvokeActionFlow($actionFlowId: String!, $args: Json!) {
fz_invoke_action_flow_default_by_latest_version(
actionFlowId: $actionFlowId
args: $args
)
}{
"actionFlowId": "d3ea4f95-5d34-46e1-b940-91c4028caff5",
"args": { "order_id": 10001 }
}返回值来自行为流声明的出参。
异步调用
先创建任务:
mutation CreateActionFlowTask($actionFlowId: String!, $args: Json!) {
fz_create_action_flow_task(
actionFlowId: $actionFlowId
args: $args
)
}返回的长整数是 taskId。随后可以订阅结果:
subscription ListenActionFlowResult($taskId: Long!) {
fz_listen_action_flow_result(taskId: $taskId) {
status
output
}
}不使用 Subscription 时,可以轮询:
query GetActionFlowResult($taskId: Long!) {
fz_action_flow_result(taskId: $taskId) {
status
output
}
}output 是行为流声明的出参;可用状态以 GraphiQL 中的 TaskStatus 枚举为准。
AI 智能体
Runtime Schema 为兼容既有接口,仍使用 fz_zai_* 字段前缀;产品中的功能名称为 AI 智能体。
| 字段 | 类型 | 说明 |
|---|---|---|
fz_zai_create_conversation | mutation | 创建会话。 |
fz_zai_listen_conversation_result | subscription | 监听流式或最终结果。 |
fz_zai_send_ai_message | mutation | 向已有会话发送消息。 |
fz_zai_provide_more_information | mutation | 为等待补充信息的工具调用提供信息。 |
fz_zai_stop_responding | mutation | 停止当前响应。 |
fz_zai_delete_conversation | mutation | 删除会话。 |
创建会话时,inputArgs 的字段来自 AI 智能体配置。普通参数直接使用参数名;单个媒体参数使用 {name}_id,媒体数组使用 {name}_ids。
mutation CreateAgentConversation(
$inputArgs: Map_String_ObjectScalar!
$agentId: String!
) {
fz_zai_create_conversation(
inputArgs: $inputArgs
zaiConfigId: $agentId
)
}{
"agentId": "zai_01HZXEXAMPLE",
"inputArgs": {
"question": "请总结这篇文章",
"cover_id": 1020000000000097
}
}使用返回的 conversationId 监听结果:
subscription ListenAgentResult($conversationId: Long!) {
fz_zai_listen_conversation_result(conversationId: $conversationId) {
conversationId
status
data
reasoningContent
images {
id
url
}
}
}会话状态包括 CREATED、IN_PROGRESS、THINKING_CHAIN_STREAMING、STREAMING、COMPLETED、FAILED 和 CANCELED。流式文本可能多次返回;应以最终状态判断本次响应是否结束。
继续多轮会话时,使用固定的消息参数,而不是创建会话时的自定义参数名:
mutation SendAgentMessage(
$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
)
}发送消息、停止响应和删除会话都要求当前身份有权访问该会话。操作后继续监听同一个 conversationId。
第三方 API
在 API 中配置并发布的接口会生成 fz_api_{api_unique_id} 字段。实际字段名、Operation 类型、入参类型和响应字段取决于当前 API 配置,请直接从 GraphiQL 复制。
mutation CallCreateOrderApi($input: fz_api_create_order_input!) {
fz_api_create_order(input: $input) {
responseCode
responseStatus
responseContentType
fz_api_create_order_response {
order_id
status
}
}
}{
"input": {
"order_id": 10001,
"amount": 99
}
}先检查 responseCode 和 responseStatus,再读取配置生成的结构化响应字段。
旧版第三方 API 可能仍以 operation_{operationId} 暴露,并将请求体生成为 fz_body 参数。旧项目应以 GraphiQL 中仍存在的字段为准;新集成使用当前 API 功能。
媒体资源
通过 Runtime API 上传图片、视频和文件分为三步:
- 计算文件内容的 MD5,并转换为 Base64 字符串。
- 调用 V2 预签名字段,获取
uploadUrl、uploadHeaders、contentType和资源 id。 - 使用返回的 URL 和全部请求头上传原始文件,再把资源 id 写入数据或传给行为流、AI 智能体。
| 资源 | 单个资源字段 | 批量字段 | 返回的资源 id |
|---|---|---|---|
| 图片 | getImagePresignedUrlV2 | presignedImageListV2 | imageId |
| 视频 | getVideoPresignedUrlV2 | presignedVideoListV2 | videoId |
| 文件 | getFilePresignedUrlV2 | — | fileId |
以下为图片示例;imageSuffix、acl 等枚举值以 GraphiQL 为准:
query PrepareImageUpload($md5: String!, $format: MediaFormat!) {
getImagePresignedUrlV2(imgMd5Base64: $md5, imageSuffix: $format) {
imageId
uploadUrl
uploadHeaders
downloadUrl
contentType
}
}上传文件时,向 uploadUrl 发起上传请求,使用 uploadHeaders 中返回的全部请求头,并将原始文件作为请求体。不要自行省略或改写签名请求头。
常见问题
| 问题 | 检查方法 |
|---|---|
permission denied | 检查是否传入正确身份,以及该身份是否拥有数据、行为流、AI 智能体或 API 权限。 |
Cannot query field | 刷新 GraphiQL Schema,确认变更已经同步或发布,并使用实际生成的字段名。 |
| Variable 类型不匹配 | 在 GraphiQL 中查看参数的非空标记、列表结构和标量类型。不要根据其他项目猜测类型。 |
HTTP 状态正常但 data 为空 | 同时检查响应中的 errors;第三方 API 还应检查 responseCode。 |
| Subscription 没有结果 | 确认使用订阅地址、graphql-ws 协议和 connection_init.payload.authToken。 |
| 异步行为流没有完成 | 使用 fz_action_flow_result 查询状态,并结合行为流运行日志排查节点错误或超时。 |
| AI 智能体会话无法继续 | 检查会话状态、当前身份是否拥有该会话,以及是否仍有上一条消息正在生成。 |
| 上传后无法使用资源 | 确认上传请求包含全部 uploadHeaders,并使用预签名响应返回的资源 id。 |
| 找不到第三方 API 字段 | 确认 API 已发布,并在 GraphiQL 中搜索其 API 唯一标识。 |
更多 GraphQL 语法请参考 GraphQL 官方文档 。