
Hasura 事件触发器 × AWS Lambda 实战Node.js 8 编写回写数据库的 Mutation Webhook【免费下载链接】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本文以仓库中 aws-lambda/nodejs8/mutation 示例 为蓝本完整演示如何在 Hasura GraphQL EngineHGE上配置数据库事件触发器并用 AWS LambdaNode.js 运行时作为 webhook在 notes 表发生数据变更时自动向 note_revision 表写入一条修订记录。读完本文你将掌握事件触发器建表规范、Lambda 打包与部署流程、webhook 环境变量配置以及从触发器 payload 解析数据并发起 GraphQL mutation 回写数据库的完整链路。事件触发器工作流APIs、后台任务、GraphQL mutations 写入 Postgres 后Hasura 监听变更并把事件分发给 Serverless 函数与微服务图源 event-triggers/README.md。场景概述为什么要在事件里再写一次库本示例演示的是一种非常典型的事件驱动业务模式当主表数据发生变化时自动生成一条审计/修订记录。具体来说notes表保存笔记正文note。每当 notes 表发生 INSERT / UPDATE / DELETEHasura 事件触发器就会把变更事件发送给 Lambda。Lambda 解析事件 payload取出被修改的笔记内容再调用 HGE 的 GraphQL mutation 接口向note_revision表插入一条修订记录。这一触发 → 回写闭环的价值在于业务写入与衍生数据的生成被完全解耦客户端只需要执行一次 mutation修订历史由 webhook 异步完成不会阻塞主请求。整个方案由 community/boilerplates/event-triggers 仓库提供除了 Node.js 之外还提供了 Go 与 Python 等语言版本。前置条件已有一个可访问的 Hasura GraphQL Engine 实例并配置了 admin secretACCESS_KEY即此密钥。一个已启用计费的 AWS 账户用于创建 Lambda 函数与 API Gateway。第一步在 HGE 中创建基础表先在 Hasura Console 中创建两张表作为整个示例的数据模型。表notes笔记主表。字段类型idInteger auto-incrementnoteText表note_revision修订记录表。字段类型idInteger auto-incrementnoteTextnote_idInteger外键关联 notes.idupdate_atTimestamp默认值now()note_revision.note_id指向notes.id形成一对多的修订历史关系update_at使用数据库默认值now()因此 Lambda 回写时无需显式传时间戳。第二步编写并打包 Lambda 函数本示例的源码位于 mutation/index.js。核心逻辑分三块读取环境变量、定义回写用的 GraphQL mutation、解析事件并执行请求。1. 依赖安装与打包在示例目录下依次执行npm install zip -r hge-mutation.zip .npm install依据 package.json 安装唯一依赖node-fetch示例中为^3.3.2用于向 HGE 发起 HTTP 请求。随后将整个目录含node_modules打包成hge-mutation.zip以便上传到 AWS。2. 关键实现拆解const accessKey process.env.ACCESS_KEY; const hgeEndpoint process.env.HGE_ENDPOINT; const query mutation updateNoteRevision ($noteId: Int!, $data: String!) { insert_note_revision (objects: [ { note_id: $noteId, note: $data } ]) { affected_rows } } ;回写动作是一个标准 GraphQL mutationinsert_note_revision接收noteId与data两个变量向修订表插入一行并返回affected_rows用于校验写入是否成功。事件处理入口exports.handlerexports.handler async (event) { try { const qv { noteId: event.body.event.data.old.id, data: event.body.event.data.old.note }; const result await fetch(hgeEndpoint /v1/graphql, { method: POST, body: JSON.stringify({ query: query, variables: qv }), headers: { Content-Type: application/json, x-hasura-admin-secret: accessKey }, }); const { errors, data } await result.json(); if (errors) { throw new Error(errors); } else { return { statusCode: 200, body: success }; } } catch (e) { return { statusCode: 400, body: cannot parse hasura event }; } };几个值得注意的实现细节payload 结构Hasura 事件经 API Gateway 包装后事件本体位于event.body其中event.body.event.data.old保存变更前的旧行数据DELETE 事件也依赖它event.body.event.data.new保存新行数据。这里取old.id与old.note作为修订记录的来源字段。请求端点GraphQL 请求发往hgeEndpoint /v1/graphql即 HGE 的 GraphQL API 根路径。鉴权方式通过请求头x-hasura-admin-secret携带ACCESS_KEY环境变量完成管理员鉴权从而获得执行 mutation 的权限。容错策略无论解析失败还是 GraphQL 返回errors都会返回statusCode: 400并附上 cannot parse hasura event 的提示体便于在 CloudWatch 中排查。对照其他语言版本可以看出同样的模式Go 版本在 mutation.go 中显式定义了HasuraEvent、Event、Data等结构体来反序列化 payload并通过event.Data.Old[id]与event.Data.New[note]取值Python 版本在 mutation.py 中通过json.loads(event[body])解析后同样读取data[old][id]与data[old][note]。这说明event.body.event.data.old/new是事件触发器跨语言的统一约定格式。第三步在 AWS 上创建并配置 Lambda在 AWS 控制台创建 Lambda 函数本示例选择Node.js 8.10作为运行时也兼容其他 Node.js 版本只需保证index.handler导出形式不变选择 start from scratch从零创建。为函数添加API Gateway作为触发器并创建一个 API 路由使 Lambda 拥有一个可被 Hasura 调用的 HTTPS 端点。上传第二步生成的hge-mutation.zip确认处理函数Handler设置为index.handler。在 Lambda 的环境变量中配置两项必填项环境变量说明ACCESS_KEY初始化 HGE 时配置的 admin secret用于 GraphQL 请求鉴权HGE_ENDPOINT你的 HGE 实例所在 URL如https://my-hge.example.com之后代码中的process.env.ACCESS_KEY与process.env.HGE_ENDPOINT即会被 AWS 注入。第四步在 Hasura 中创建事件触发器打开 Hasura Console 的Events事件标签页点击添加触发器。触发器选择对notes表的insert、update、delete全部操作生效即三种数据变更都会触发 webhook。将上一步 API Gateway 生成的 API 端点粘贴为webhook URL保存完成配置。保存后可以回到 Console 对 notes 表做一次插入或更新观察 note_revision 表是否自动出现对应修订行同时可在 Lambda 的 CloudWatch Logs 中查看每次调用的日志与返回值200 success或400 cannot parse hasura event。常见问题与排查要点触发器未触发检查 webhook URL 是否可从公网访问API Gateway 是否正确暴露确认触发器覆盖了你所执行的操作类型。返回 400 cannot parse hasura event多因event.body结构与预期不符如未走 API Gateway 代理集成或data.old在 INSERT 事件中字段缺失。可在 Lambda 中临时打印整个event对象核对结构。mutation 鉴权失败确认ACCESS_KEY与 HGE 实际配置的 admin secret 一致且请求头字段名x-hasura-admin-secret未被修改。依赖版本提示本示例package.json声明的是node-fetch^3.3.2如需在旧版 Node.js 8.10 运行时下使用建议自行锁定兼容的 2.x 版本核心逻辑解析 payload、调用/v1/graphql与运行时版本无关。延伸阅读事件触发器在其他云平台的实现azure-functions、google-cloud-functions、netlify-functions、zeit-now。同一目录下的 echo 示例 展示了如何按opINSERT / UPDATE / DELETE区分事件类型并直接回显 payload适合作为理解事件结构的入门参考。事件触发器的通用架构说明见 community/boilerplates/event-triggers/README.md。【免费下载链接】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),仅供参考