基于 Azure Functions 编写 Hasura Event Triggers 回调的 Node.js 实践指南(echo 与 mutation 双示例详解)

发布时间:2026/9/19 18:26:05
基于 Azure Functions 编写 Hasura Event Triggers 回调的 Node.js 实践指南(echo 与 mutation 双示例详解)
基于 Azure Functions 编写 Hasura Event Triggers 回调的 Node.js 实践指南echo 与 mutation 双示例详解【免费下载链接】graphql-engineBlazing fast, instant realtime GraphQL APIs on all your data with fine grained access control, also trigger webhooks on database events.项目地址: https://gitcode.com/gh_mirrors/gr/graphql-engine本篇技术指南以 Hasura GraphQL Engine 开源仓库中 azure-functions/nodejs 事件触发器示例 为核心系统讲解如何在 Azure FunctionsNode.js上实现两种典型的 Event Triggers 回调echo回显并理解事件 payload与mutation收到 insert 事件后通过 GraphQL mutation 写回关联数据。读完本文你将掌握事件触发器的 payload 结构、Azure Functions 的部署与本地调试流程、ADMIN_SECRET/HGE_ENDPOINT环境变量与X-Function-Key鉴权配置以及在 Hasura Console 中完成触发器注册与验证的完整实战方案。背景Hasura Event Triggers 与 Webhook 回调Hasura Event Triggers 允许你在数据库表发生INSERT、UPDATE、DELETE操作时自动向外部 Webhook 发送事件通知从而实现数据库事件驱动业务逻辑。其整体架构见下图为数据库操作触发事件 → Hasura 捕获事件并携带 payload 调用你配置的 Webhook 地址 → Webhook 返回响应。本仓库在 community/boilerplates/event-triggers/ 目录下为多种语言/平台提供了官方样板代码其中 azure-functions/nodejs 专门针对 Azure Functions 平台包含两个核心示例示例目录核心作用echoecho/回显触发 payload帮助理解事件数据结构和解析方式mutationmutation/在 insert 事件上使用 GraphQL mutation 插入关联数据演示如何通过 GraphQL 与数据库交互示例一echo —— 理解并回显事件 Payloadecho 示例的功能非常纯粹将 Hasura 发送过来的事件请求体原样返回。它最适合作为学习事件触发器 payload 结构的入门样例也常被用来排查Hasura 到底往 Webhook 发了什么。建表准备在 PostgreSQL 中创建一张最简单的表notes: id: int note: text这张表将作为事件触发器的数据源。之后在 Hasura Console 的 Events 页面对该表配置触发器具体步骤见下文在 Hasura 中注册触发器一节。函数实现解析核心代码位于 echo/HTTPTrigger/index.js完整内容如下module.exports function (context, req) { context.log(JavaScript HTTP trigger function processed a request.); if (req.body req.body) { context.res { // status: 200, /* Defaults to 200 */ body: req.body }; } else { context.res { status: 400, body: Please pass a request body }; } context.done(); };其逻辑要点函数接收contextAzure Functions 上下文与reqHTTP 请求对象两个参数只要请求携带 body就将其原样写入context.res.body返回HTTP 状态码默认 200若没有 body则返回400及提示文本Please pass a request body。由于它直接回显事件内容你可以借此观察 Hasura Event Trigger 发送的完整 payload 结构包括event.op操作类型、event.dataold/new数据行、table表信息等字段——这些字段正是下文 mutation 示例中所解析的内容。HTTP 触发器绑定配置Azure Functions 的触发器绑定定义在 echo/HTTPTrigger/function.json{ disabled: false, bindings: [ { authLevel: anonymous, type: httpTrigger, direction: in, name: req, methods: [get, post] }, { type: http, direction: out, name: res } ] }关键点authLevel为anonymous表示默认不要求函数级鉴权若你在门户中启用 Authorization level则需要在调用时携带X-Function-Key头详见下文鉴权小节methods同时开放了get与postHasura 通过 HTTP POST 投递事件入站绑定名req与出站绑定名res与index.js中的参数一一对应。宿主级配置见 echo/host.json其中声明了functionTimeout: 00:00:3030 秒超时、routePrefix: 路由无前缀以及consoleLevel: verbose的详细日志追踪方便调试。示例二mutation —— 事件驱动下用 GraphQL 写入关联数据mutation 示例演示了一个经典场景当notes表发生更新时自动把变更前的快照写入一张note_revision修订历史表。这展示了在事件触发器中通过 GraphQL mutation 与 Hasura GraphQL API 交互的标准做法。建表准备需要创建两张表并建立外键关联表名: notes 列: id: Integer 自增 note: Text 表名: note_revision 列: id: Integer 自增 note: Text note_id: Integer (外键关联 notes.id) update_at: Timestamp, 默认 now()note_revision.note_id指向notes.id用于在修订记录与笔记之间建立关联。函数实现解析核心代码位于 mutation/HTTPTrigger/index.js完整内容如下const { query } require(graphqurl); const ADMIN_SECRET process.env.ADMIN_SECRET; const HGE_ENDPOINT process.env.HGE_ENDPOINT; const MUTATION_NOTE_REVISION mutation updateNoteRevision ($noteId: Int!, $data: String!) { insert_note_revision (objects: [ { note_id: $noteId, note: $data } ]) { affected_rows } } ; module.exports function (context, req) { context.log(JavaScript HTTP trigger function processed a request.); try { context.log(Inside); const { event: {op, data}, table } req.body; context.log(data); context.log(data.new.id); const qv {noteId: data.old.id, data: data.old.note}; const hgeResponse query({ query: MUTATION_NOTE_REVISION, endpoint: HGE_ENDPOINT /v1/graphql, variables: qv, headers: { x-hasura-admin-secret: ADMIN_SECRET } }).then((response) { context.log(response); context.log(After query); context.res { body: { error: false, data: response } }; context.done(); }).catch((error) { console.error(JSON.stringify(error)); context.res { status: 500, body: { error: true, data: JSON.stringify(error) } }; context.done(); }); } catch(e) { context.res { status: 400, body: An error occured. }; context.done(); } };其逻辑要点读取环境变量ADMIN_SECRET与HGE_ENDPOINT从进程环境变量中读取下文环境变量与鉴权小节有详细说明解析事件 payload通过解构const { event: {op, data}, table } req.body;获取操作类型op、数据data与表名table并打印日志构造修订数据qv {noteId: data.old.id, data: data.old.note}取更新前的old行数据——即把旧值快照写入修订表调用 Hasura GraphQL API使用graphqurl库向HGE_ENDPOINT /v1/graphql发起 mutation携带x-hasura-admin-secret请求头完成 admin 鉴权结果处理成功时返回{ error: false, data: response }HTTP 200GraphQL 调用失败时返回500与错误信息解析阶段异常则返回400。需要特别留意的是示例中使用了data.old.id与data.old.note说明该示例预期在UPDATE事件携带old数据下工作而变量类型声明为Int!与String!与id/note的列类型保持一致。从代码结构看若触发器同时选择了INSERT操作old字段可能为空实际使用时需按事件类型分别处理data.new与data.old。依赖与绑定配置mutation/HTTPTrigger/package.json 声明了运行所需的依赖dependencies: { graphqurl: ^0.3.1, node-fetch: ^2.2.0 }graphqurl轻量级 GraphQL 客户端用于在 Node.js 中发起 mutation/querynode-fetchgraphqurl底层的 HTTP 请求实现依赖。其 HTTPTrigger/function.json 与 echo 示例完全一致authLevel: anonymous、methods: [get, post]宿主配置 host.json 同样声明了 30 秒超时与 verbose 级别追踪。两示例目录中各包含一个 sample.dat 文件内容为{name: Azure}用于 Azure 门户的在线测试占位不是事件触发器的真实 payload。在 Azure 上部署与发布函数两个示例的部署流程完全一致echo README 与 mutation README 均给出了完整的 Azure CLI 命令序列az group create --name my-functions-group --location southindia az storage account create --name myfunctionsstorage --location southindia --resource-group my-functions-group --sku Standard_LRS az functionapp create --name myfunctionsapp --storage-account myfunctionsstorage --resource-group my-functions-group --consumption-plan-location southindia func azure login func azure subscriptions set Free Trial func azure functionapp publish myfunctionsapp各命令的职责拆解az group create创建资源组my-functions-group示例位于southindia区域可按需替换为其他区域az storage account create为函数应用创建配套存储账户Standard_LRS为本地冗余的标准存储 SKUaz functionapp create创建消费计划Consumption Plan下的函数应用按实际执行时长计费func azure login/func azure subscriptions setCore Tools 登录 Azure 并选择目标订阅示例中为Free Trialfunc azure functionapp publish将当前目录下的函数发布到云端myfunctionsapp。发布成功后你可以在 Azure 门户的函数 URL 页面拿到形如https://myfunctionsapp.azurewebsites.net/api/HTTPTrigger的 Webhook 地址受host.json中routePrefix: 影响路由前缀可能为空。环境变量与鉴权配置部署完成后需要为函数应用配置两个关键环境变量Azure 门户 → 函数应用 → 配置 → 应用程序设置环境变量含义示例值ADMIN_SECRETHasura 管理密钥即启动 Hasura 时的HASURA_GRAPHQL_ADMIN_SECRET用于在调用/v1/graphql时通过x-hasura-admin-secret头鉴权myadminsecretkeyHGE_ENDPOINTHasura GraphQL Engine 的地址不包含/v1/graphql路径代码中会拼接http://localhost:8080或云实例地址mutation 示例正是通过这两者完成对 Hasura 的调用endpoint: HGE_ENDPOINT /v1/graphql、headers: { x-hasura-admin-secret: ADMIN_SECRET }。关于鉴权还有两点补充若 Azure Function 的 Authorization level 已启用function.json中为anonymous但门户上可能提升则在 Hasura 配置 Webhook 时需添加X-Function-Key请求头携带函数访问密钥实际生产环境中建议为 Hasura 配置专用角色或使用更细粒度的权限而示例使用 admin secret 是为了演示便捷请结合 server 源码中的权限体系 自行评估安全边界。在 Hasura 中注册触发器部署好函数后回到 Hasura Console 完成触发器注册echo README 中的步骤打开 Events事件标签页点击添加触发器Add Trigger选择需要触发的数据库表与操作示例中要求同时勾选 insert、update、delete 三种操作这样能观察到三类事件的 payload 差异将函数 URL 粘贴为 Webhook 地址保存后对表执行相应 DML 操作即可看到函数被调用可在函数日志中观察 payload 或写入结果。本地调试与日志查看发布之前可以先在本地运行调试func host start该命令会启动本地 Functions 宿主并输出本地 HTTP 端点供你结合 Hasura如通过docker-compose本地实例进行联调。日志查看命令func azure functionapp logstream myfunctionsapplogstream会流式输出云端函数的实时日志。由于 host.json 中设置了consoleLevel: verboseecho/mutation 示例中所有的context.log(...)输出如回显的 payload、data.new.id、GraphQL 响应等都会完整呈现便于排查问题。源码级小结两个示例的工程结构最后将两个示例的完整目录结构梳理如下方便对照阅读均在 azure-functions/nodejs 下nodejs/ ├── README.md # 顶层索引echo 与 mutation 简介 ├── echo/ │ ├── README.md # 建表、部署、触发配置说明 │ ├── host.json # 宿主配置超时/路由/日志 │ └── HTTPTrigger/ │ ├── function.json # HTTP 触发器绑定anonymous, get/post │ ├── index.js # 回显 payload 的函数实现 │ └── sample.dat # 门户在线测试占位数据 └── mutation/ ├── README.md # 双表建表、部署、触发配置说明 ├── host.json └── HTTPTrigger/ ├── function.json ├── index.js # GraphQL mutation 写修订记录 ├── package.json # graphqurl / node-fetch 依赖 └── sample.dat一句话总结echo 帮你读懂事件 payloadmutation 教你如何在回调里回写数据库。两者配合 Azure Functions 的func工具链与ADMIN_SECRET/HGE_ENDPOINT配置即可快速搭建一套数据库变更 → 云端函数 → GraphQL 业务逻辑的事件驱动流水线。仓库中 event-triggers.md 与 docs 文档的事件触发器章节 还提供了更完整的触发器能力说明可进一步延伸阅读。【免费下载链接】graphql-engineBlazing fast, instant realtime GraphQL APIs on all your data with fine grained access control, also trigger webhooks on database events.项目地址: https://gitcode.com/gh_mirrors/gr/graphql-engine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考