ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

在 Google Cloud Functions 上部署 Hasura 远程 GraphQL Schema:Node.js + Apollo Server 实战指南

2026/9/19 13:40:34 拓冰建站 浏览量
在 Google Cloud Functions 上部署 Hasura 远程 GraphQL Schema:Node.js + Apollo Server 实战指南 在 Google Cloud Functions 上部署 Hasura 远程 GraphQL SchemaNode.js Apollo Server 实战指南【免费下载链接】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 仓库中的官方样板代码boilerplate为核心讲解如何用 Node.js Apollo Server 编写一个自定义 GraphQL 服务并将其部署到 Google Cloud Functions最终与 Hasura 自动生成的 GraphQL API 合并Merge为统一端点。读完本文你将掌握该样板代码的文件结构与 Schema/Resolver 实现、本地开发流程、gcloud部署命令以及通过 Console / CLI / Metadata API 三种方式把远程服务接入 GraphQL Engine 的完整链路。为什么需要远程 Schema样板代码Hasura GraphQL Engine 的核心能力是围绕数据库自动生成 CRUD 实时 GraphQL API并内置细粒度授权与访问控制。但业务中常常存在无法用数据库 CRUD 直接表达的逻辑——例如支付 API、调用天气等第三方数据源、在插入前执行校验的定制 Mutation。remote-schemas.md仓库根目录明确给出了远程 Schema 的典型适用场景定制 Mutation例如在 insert 前执行业务校验在 GraphQL Engine 的统一 API 之后接入支付等功能提供一致的访问接口从其他数据源拉取异构数据如天气 API 或另一个数据库。实现方式也很直接自行编写一个任意语言/框架的 GraphQL 服务把 HTTP 端点交给 Hasura由 GraphQL Engine 自动完成 Schema 合并schema stitching。community/boilerplates/remote-schemas/README.md中给出了面向不同云平台的样板代码索引AWS Lambda、Azure Functions、Google Cloud Functions、Zeit Now 等。本文聚焦其中 Google Cloud Functions 下的 Node.js 版本其样板代码位于 community/boilerplates/remote-schemas/google-cloud-functions/nodejs。整个合并机制可用下图概括业务侧 GraphQL 服务与 Hasura 生成的 API 统一暴露给客户端由 GraphQL Engine 在中间完成 Schema 拼接与转发。样板代码目录结构与技术栈先看该 boilerplate 的文件构成相对仓库根目录community/boilerplates/remote-schemas/google-cloud-functions/nodejs/ ├── README.md # 官方使用说明本文的原始依据 ├── index.js # Schema(typeDefs) 与 Resolvers 定义 ├── localDev.js # 本地开发服务器入口Apollo Server ├── googleCtx.js # Cloud Functions 部署入口导出 handler └── package.json # 依赖清单main 指向 googleCtx.js按 README.md 的记录该样板的技术栈为运行时Node.js 8.10对应部署命令中的--runtime nodejs8这是样板代码创作时代的记录如今 Google Cloud Functions 的运行时版本已迭代多代实际部署时应选用当时仍受支持的 Node 运行时并相应调整依赖版本平台Google Cloud FunctionsHTTP 触发的 serverless 函数框架/库Apollo ServerGraphQL 服务框架Cloud Functions 场景下使用其适配包apollo-server-cloud-functions。依赖声明位于 package.json{ name: google-cloud-functions-nodejs, version: 1.0.0, main: googleCtx.js, dependencies: { apollo-server-cloud-functions: ^2.4.8, graphql: ^0.13.1, graphql-tag: ^2.10.1 } }注意main字段指向googleCtx.js说明面向 Cloud Functions 的真正部署入口是googleCtx.js中导出的handler而index.js只是被复用的 Schema/Resolver 定义模块。这种定义与运行环境分离的结构正是同一套 GraphQL 定义既能本地调试、又能无改动部署到云函数的可移植设计。Schema 与 Resolver最小可运行的 GraphQL 定义核心业务定义全部收敛在 index.js 中const gql require(graphql-tag); const typeDefs gql type Query { hello: String } ; const resolvers { Query: { hello: () world, }, }; exports.typeDefs typeDefs; exports.resolvers resolvers;要点拆解typeDefs使用graphql-tag的模板标签语法声明 Schema只有一个Query.hello: String根字段resolvers为hello提供实现() world通过exports导出typeDefs与resolvers供本地开发与云函数两个入口复用。对一个将要接入 Hasura 的远程 Schema 而言这段代码虽小却体现了三个必须满足的契约必须是标准 GraphQL Schema且类型名与字段名全局唯一Hasura 合并远程 Schema 时要求跨所有合并 Schema 类型名/节点名唯一详见 remote-schemas.md 的 Caveats 一节必须提供HTTP 端点供 GraphQL Engine 转发请求生产环境中通常会继续扩展Mutation、加入鉴权 headers、接入数据库等样板只演示最小闭环。本地开发一条命令起一个 GraphQL Playground在进入云函数部署之前先在本地验证 Schema 与 Resolver 的行为。README.md 给出的流程是# 进入样板目录 cd community/boilerplates/remote-schemas/google-cloud-functions/nodejs # 安装依赖--no-save 表示不写入 package.json示例环境可按需调整 npm i --no-save apollo-server # 启动本地开发服务器 node localDev.js启动成功后控制台输出Server ready at http://localhost:4000/浏览器访问localhost:4000即可打开 GraphQL Playground执行{ hello }得到{ data: { hello: world } }。本地入口 localDev.js 的实现如下const { ApolloServer } require(apollo-server); const { typeDefs, resolvers } require(./index); const server new ApolloServer({ typeDefs, resolvers }); server.listen().then(({ url }) { console.log(schema ready at ${url}); });这里使用的是通用版apollo-server包server.listen()默认监听4000端口并自带 Playground 界面一旦确认本地可查询就可以放心地把它部署到云端——因为 Schema 与 Resolver 是从index.js共享出来的同一份定义。部署到 Google Cloud Functions1. 准备 gcloud CLI按 README.md 的步骤首先安装gcloud命令行工具并完成登录、选择项目gcloud config set project your-project-id等初始化操作。2. 编写云函数入口部署入口 googleCtx.js 使用apollo-server-cloud-functions适配器把 Apollo Server 包装为 Cloud Functions 的 HTTP handlerconst { ApolloServer } require(apollo-server-cloud-functions); const { typeDefs, resolvers } require(./index); const server new ApolloServer({ typeDefs, resolvers, playground: true, introspection: true, context: ({ req, res }) ({ headers: req.headers, req, res, }), }); exports.handler server.createHandler({ cors: { origin: *, credentials: true, allowedHeaders: Content-Type, Authorization }, });这段代码值得注意的工程细节playground: true与introspection: true允许在线上打开 Playground 与内省查询方便调试生产环境可按需关闭context把 Cloud Functions 的req/res及请求 headers 注入到每个 GraphQL 请求的 context 中后续 Resolver 可以读取客户端传来的 headers——这与 Hasura 远程 Schema 的 header 转发机制可以很好地配合createHandler中显式配置了CORSorigin: *配合credentials: true允许任意来源携带Content-Type与Authorization头访问。由于 Hasura GraphQL Engine 通常运行在其他域名/容器中正确的 CORS 配置是远程 Schema 能被 Engine 正常调用的关键前提。3. 执行 gcloud 部署命令在原样板目录下运行命令取自 README.mdgcloud functions deploy hello-graphql --entry-point handler --runtime nodejs8 --trigger-http参数含义参数作用hello-graphql云函数名称--entry-point handler指定函数入口为googleCtx.js导出的handler--runtime nodejs8Node.js 运行时版本样板记录时的版本请按 GCP 现行支持的运行时调整--trigger-http使用 HTTP 触发器返回可被公网访问的 HTTPS URL部署成功后gcloud会输出函数的触发信息格式如下示例httpsTrigger: url: https://us-central1-hasura-test.cloudfunctions.net/hello-graphql把httpsTrigger.url的值记录下来——这就是要交给 Hasura 的 GraphQL 端点。把部署好的服务接入 Hasura GraphQL Engine远程服务上线后下一步是把它合并进 GraphQL Engine。官方文档 adding-schema.mdx 提供了 Console、CLI、Metadata API 三种等价方式。方式一Console 图形界面在 Hasura Console 左侧进入Remote Schemas页签点击Add填写Remote Schema name该远程 Schema 的别名在同一个 GraphQL Engine 实例上必须唯一GraphQL server URL上一步拿到的httpsTrigger.url也可通过环境变量注入Headers可选可勾选转发客户端全部 headers也可追加静态 header 或header 名-环境变量名形式的动态 header。点击Add Remote Schema完成合并即可在 GraphiQL 页签中查询hello字段。方式二CLI 与 Metadata 文件在metadata/remote_schemas.yaml中添加条目- name: hello-graphql definition: url: https://us-central1-hasura-test.cloudfunctions.net/hello-graphql timeout_seconds: 60 forward_client_headers: true然后应用元数据hasura metadata apply方式三Metadata API向/v1/metadata发送add_remote_schema请求以 admin 角色为例POST /v1/metadata HTTP/1.1 Content-Type: application/json X-Hasura-Role: admin { type: add_remote_schema, args: { name: hello-graphql, definition: { url: https://us-central1-hasura-test.cloudfunctions.net/hello-graphql, forward_client_headers: true, timeout_seconds: 60 } } }集成注意事项网络可达性如果 GraphQL Engine 运行在 Docker 容器中必须确保容器能访问云函数端点用环境变量注入 URL 时需在docker run时通过-e REMOTE_SCHEMA_ENDPOINT...传入环境变量必须在添加远程 Schema 时就存在且有效因为 Engine 是在添加时解析并保存 URL/header 值的当前合并机制的限制见 remote-schemas.md Caveats所有合并 Schema 的类型名/节点名必须全局唯一大小写敏感同一查询中的所有顶层节点必须来自同一个 GraphQL 服务远程服务的 Subscription 暂不支持。实战演进建议这个hello样板只完成了最小闭环在实际项目中通常会沿以下几个方向扩展均可在本样板结构内完成扩展 Schema 与 Resolver在index.js中加入Mutation、更多 Query 字段或通过graphql-tools的makeExecutableSchema组合多个模块接入数据源在 Resolver 中调用 REST API、数据库或第三方 GraphQL 服务这正是远程 Schema 解决数据库之外的自定义逻辑的核心价值鉴权与 header 透传利用googleCtx.js注入的context.headers读取客户端鉴权信息配合 Hasura 的forward_client_headers与自定义 headers 配置完成端到端安全链路升级运行时与依赖样板记录的 Node 8.10 /nodejs8运行时与apollo-server-cloud-functions ^2.4.8、graphql ^0.13.1均属历史版本部署到当前 GCP 环境时应升级到受支持的 Node 版本并同步升级 Apollo Server 与 graphql 依赖同时验证 CORS 与 Playground 配置在新版本下的行为。通过本文的完整流程你可以把任意自定义 GraphQL 逻辑以 serverless 函数的形式部署到 Google Cloud再无缝合并进 Hasura 的统一 GraphQL API——这也是官方提供的众多远程 Schema 样板community/boilerplates/remote-schemas中Google Cloud Functions 场景下的标准做法。【免费下载链接】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),仅供参考