Malla文档

查询与集成

连接 REST、GraphQL 和 CMS,把密钥保留在服务端,并选择静态、服务端或客户端模式。

用户指南

集成只需配置一次,就能把站点连接到外部服务。查询在页面上通过集成获取数据,绑定则以 queries.name.data 读取结果。

集成

REST任意 JSON API,可设置基础 URL、默认请求头,以及 none、bearer、basic 或 API-key 认证。
GraphQL一个接口地址加认证。会对结构进行一次内省,为自动补全提供支持。
CMS内置,无需配置。支持按筛选、排序和引用列出和获取条目。
PostgreSQL任意 Postgres(Neon、Supabase、RDS…):通过 TLS 执行参数化 SQL,只读查询,最多 1,000 行。
Supabase通过 REST API 执行查询、插入、更新、删除和调用函数,支持行级安全。
Airtable按视图或公式列出记录,并可创建、更新或删除记录。
Google Sheets以对象形式读取行,借助服务账号追加行和更新区域。
Resend从工作流发送事务性邮件。
Claude and OpenAI生成、总结和提取文本,可选择输出符合某个结构的 JSON。

在 Data 工作区中添加集成。填写连接设置,输入密钥(令牌、密码、API 密钥),保存,然后点击 Test connection 下的 Run test。管理员负责创建和编辑集成;编辑者可以在查询中使用和测试它们。

需要准备什么

表单标签来自设置项名称,所以会显示成 Base url 或 Ssl 这样的形式。

  • REST:Base url;认证方式可以是 Bearer token、basic 认证的 Username 和 Password,或者 API key 及其请求头或查询参数名。
  • GraphQL:Endpoint;如果需要认证,再加上 Bearer token 或 API key。
  • PostgreSQL:Host、Port、Database、User 和 Password,可在服务商的连接信息中找到(Neon 在项目仪表盘上点 Connect;Supabase 在项目顶部点 Connect)。
  • Supabase:项目 API 设置中的 Project url 和 API key。anon key 遵循行级安全;service-role key 会绕过行级安全,因此只能在服务端工作流中使用。
  • Airtable:Base id(base URL 中 app… 那部分),以及在该 base 上拥有 data.records:read 权限(修改记录还需 data.records:write)的 Personal access token。
  • Google Sheets:表格 URL 中的 Spreadsheet id,以及 Service account key (JSON),并把表格共享给该服务账号的邮箱。若只读取已公开到网络的表格,一个 API key 就够了。
  • Resend:一个使用已在 Resend 中验证的域名的 Default from 发件人,以及 API key;只有发送权限的密钥就够了。
  • Claude:来自 Claude Console 的 API key。
  • OpenAI:来自 OpenAI 平台的 API key。Base url 可以指向任何兼容 OpenAI 的 API。
已发布站点上的一次客户端查询
浏览器请求 Malla 运行查询。
边缘检查页面访问权限和限流。
执行器解密密钥,调用 API。
你的 API永远接触不到访客的浏览器。

PostgreSQL

填写主机、端口、数据库和用户,并把密码作为密钥填写。使用只拥有站点所需权限的角色。编写 SQL 时使用 $1、$2… 占位符,并在 params 中传入值;值永远不会直接拼接进 SQL。Query 在只读事务中运行,因此不能修改数据;Execute 可以写入。结果以 { rows, rowCount, columns, truncated } 形式返回:用于集合列表时,把响应路径设为 rows。

创建查询

  1. 选择集成和操作

    例如 REST Request、GraphQL Query 或 CMS List items。

  2. 填写输入

    任何输入值都可以是表达式。读取变量即可让查询随之响应:vars.search、page.params.slug。

  3. 选择运行时机

    选择一种模式(见下文)。在编辑器中运行一次,即可查看结果,并获得结果字段的自动补全。

  4. 缩小结果范围

    设置一个响应路径,例如 data.items,让 queries.products.data 正好是你想要的数组。

json
{
  "name": "products",
  "integrationId": "int_shop_api",
  "operation": "rest.request",
  "input": {
    "method": "GET",
    "path": "/products",
    "query": { "search": { "$expr": "vars.search" } }
  },
  "responsePath": "data.items",
  "run": { "mode": "client", "on": "load", "debounceMs": 250 }
}

静态、服务端还是客户端

模式运行时机适用场景
Static发布时运行;结果直接写入 HTML营销页面、CMS 内容,SEO 最佳
Server每次请求时在边缘运行,可选择缓存 N 秒需要被搜索引擎收录的最新或个性化数据
Client在浏览器中运行:页面加载时以及输入变化时(带防抖),或只由工作流触发搜索、筛选、仪表盘

读取查询

  • queries.name.data:结果。
  • queries.name.loading:运行期间为 true。可以把加载指示器的可见性绑定到它。
  • queries.name.error:{ message, code } 或 null。
  • queries.name.updatedAt:最近一次结果返回的时间。

在工作流中使用 Refetch query 重新获取客户端查询。要在页面中运行会写入数据或产生费用的操作,请使用 Run server workflow 调用一个从页面调用的服务端工作流。列表通过集合列表显示查询结果。