ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

PostGraphile v4 自定义 Mutation 实战指南:用 PostgreSQL 函数构建业务级 GraphQL 变更操作

PostGraphile v4 自定义 Mutation 实战指南:用 PostgreSQL 函数构建业务级 GraphQL 变更操作 后端API网关【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址https://gitcode.com/gh_mirrors/cry/crystal点击查看免费下载导读PostGraphile 会自动为数据库表生成 CRUD Mutations但真实业务往往需要更贴合逻辑的变更操作例如密码重置、接受团队邀请、批量插入文档。自定义 MutationCustom Mutations让你把任意业务逻辑封装成 PostgreSQL 函数PostGraphile 会把它自动暴露为符合 Relay Input Object Mutations Specification 的 GraphQL mutation 字段。读完本文你将掌握自定义 Mutation 的识别规则、完整 SQL 写法、SECURITY DEFINER等安全语义、pgStrictFunctions参数控制以及resultFieldName等 Smart Tag 对结果字段的定制技巧。一、为什么需要自定义 MutationPostGraphile 默认会为每张表生成createXxx、updateXxxById、deleteXxxById等 CRUD mutation但自动生成的变更很难覆盖真实业务逻辑——比如忘记密码需要在函数内部完成令牌生成、邮件发送、记录更新等一系列操作。官方文档给出的观点是很多人会直接通过--disable-default-mutations库版本对应disableDefaultMutations: true关闭自动 mutation然后用自定义 mutation 完全接管写操作。自定义 mutation 的典型优势业务逻辑集中在数据库端一个函数即可完成多次读写的原子性操作可以对函数加SECURITY DEFINER按需绕过 RLS 与 GRANT 检查官方文档明确警告这相当于sudo务必谨慎函数返回的复合类型、标量甚至SETOF集合都能直接映射为 GraphQL 的 payload 类型。这一设定在源码中有直接体现v4 预设实现 通过disableDefaultMutations动态禁用PgMutationCreatePlugin与PgMutationUpdateDeletePlugin两个插件为自定义 mutation 让路。二、函数成为自定义 Mutation 的识别规则要让 PostGraphile 把 PostgreSQL 函数识别为自定义 mutation必须同时满足以下规则遵守 PostGraphile 通用函数限制函数必须标记为VOLATILE这也是 PostgreSQL 函数的默认值函数必须定义在被 introspection 扫描的 schema 中。关于通用函数限制function-restrictions.md 列出的不支持项包括VARIADIC可变参数函数重载函数多个同名不同签名函数因为目前无法在 GraphQL 中整洁地暴露返回裸record的函数——因为不知道record包含哪些列无法映射成 GraphQL 类型解决方法是把record改成CREATE TYPE定义的复合类型名。三、Relay 兼容的输入对象形态满足上述规则的函数会被映射为符合 Relay Input Object Mutations Specification 的形式参数收进input输入对象返回值放进 payload 类型。官方文档示例CREATE FUNCTION my_function(a int, b int) RETURNS text AS $$ … $$ LANGUAGE sql VOLATILE;对应的 GraphQL 调用方式mutation { myFunction(input: { a: 1, b: 2 }) { text } }可以看到my_function变成驼峰命名的myFunctiona、b两个入参被收纳进input: { a: 1, b: 2 }函数返回的text标量成为 payload 上的text字段。具体可用的参数如clientMutationId可以在 Ruru / GraphiQL 的文档面板中查看。四、完整示例接受团队邀请官方文档给出了一个典型的自定义 mutation——acceptTeamInvite接受团队邀请它会生成对应的 GraphQL mutationCREATE FUNCTION app_public.accept_team_invite(team_id integer) RETURNS app_public.team_members AS $$ UPDATE app_public.team_members SET accepted_at now() WHERE accepted_at IS NULL AND team_members.team_id accept_team_invite.team_id AND member_id app_public.current_user_id() RETURNING *; $$ LANGUAGE sql VOLATILE STRICT SECURITY DEFINER;对该函数有几点官方说明值得留意STRICT可选当任一参数为NULL时函数不会被调用直接返回null且不报错。这让我们可以把teamId标记为必填参数。SECURITY INVOKER默认函数以调用者的安全上下文运行即谁调用就以谁的权限执行。SECURITY DEFINER函数以定义者通常是数据库所有者的安全上下文运行可以绕过 RLS、RBAC 等安全检查。官方文档提醒使用它要像使用sudo一样小心语言选择示例用LANGUAGE sql如果需要变量、循环、if 分支等能力可改用LANGUAGE plpgsql也可以使用LANGUAGE plv8JavaScript需安装扩展或 PostgreSQL 内置的 Python、Perl、Tcl 等语言。五、快速参考忘记密码Forgot password这是 examples 目录下的快速参考示例展示了基于 examples repo schema 运行真实查询的效果。注意示例 schema 使用了graphile-contrib/pg-simplify-inflector插件来简化字段命名相比默认的 inflector 规则字段名更短更直接。GraphQL 调用mutation { forgotPassword(input: { email: benjieexample.com }) { success } }对应的 PostgreSQL 函数大致如下函数体省略号处即业务实现create function forgot_password(email text) returns boolean language plpgsql volatile as $$ ... $$; -- 可选重命名结果字段 comment on function forgot_password(email text) is resultFieldName success;执行结果{ forgotPassword: { success: true } }这个示例展示了自定义 mutation 的两个关键点函数默认把返回的boolean映射为 payload 上的boolean字段通过resultFieldNameSmart Tag 把结果字段重命名为success从而让 GraphQL 返回更语义化的 payload。resultFieldName 的底层实现resultFieldName的解析逻辑在 PgV4InflectionPlugin 的functionMutationResultFieldName中实现如果资源带有extensions.tags.resultFieldName则直接返回该 tag 值否则按返回值类型回退到integer、float、boolean、string或匿名复合类型的默认命名。更详细的用法见 Smart Tags 文档其给出的典型场景即自定义 Mutation 函数在 mutation payload 类型上的字段名。例如procedure: { authenticate: { tags: { name: login, resultFieldName: token, } } }等价的 SQL Smart Comment 写法comment on function authenticate(text, text) is EresultFieldName token\nname login;六、pgStrictFunctions把参数按默认值推断必填/可选默认情况下PostGraphile 对函数参数的 nullability 判定遵循 PostgreSQL 语义。如果你希望没有默认值的参数一律必填非空、有默认值的参数可选可以开启pgStrictFunctions。官方文档特别指出这与给函数标记STRICT相似但有个微妙区别——pgStrictFunctions下带默认值的参数仍可显式传NULL而不会让整个函数返回 null。例如CREATE FUNCTION foo(a int, b int, c int 0, d int null) ...会生成 mutationfoo(a: Int!, b: Int!, c: Int, d: Int)——a、b无默认值故必填c、d有默认值故可选。库版本配置方式在 PostGraphile v4 的库用法中通过graphileBuildOptions传入app.use( postgraphile(connectionString, schemaName, { graphileBuildOptions: { pgStrictFunctions: true, }, }), );CLI 配置方式使用 CLI 时需要借助.postgraphilerc.js配置文件做类似设置。从源码看该选项在 v4 预设 中从graphileBuildOptions解构出来并接入构建流程因此它在 v4 兼容层中是被显式支持、有实现依据的选项。七、批量插入示例Bulk Insert自定义 mutation 也支持返回集合SETOF用于一次插入多行并返回全部记录的场景。官方文档的示例CREATE FUNCTION app_public.create_documents(num integer, type text, location text) RETURNS SETOF app_public.document AS $$ INSERT INTO app_public.document (type, location) SELECT create_documents.type, create_documents.location FROM generate_series(1, num) i RETURNING *; $$ LANGUAGE sql STRICT VOLATILE;要点返回类型SETOF app_public.document让 payload 携带多条记录generate_series(1, num)配合INSERT ... SELECT一次性插入num条STRICT保证num、type、location任一为NULL时不执行VOLATILE是自定义 mutation 的识别前提之一。八、mutation 没有出现的排查思路如果自定义 mutation 没有出现在生成的 schema 中可以从 CRUD Mutations 文档 的排查清单里定位原因这些原因同样适用于自定义 mutation 场景确认服务启动时没有输出相关错误检查是否设置了--disable-default-mutations或-M、.postgraphilerc中对应项确认表或函数没有被omitSmart Comment 屏蔽确认函数定义在被扫描的 schema 中且满足VOLATILE等规则见本文第二节若使用 GraphiQL务必在请求中使用mutation { ... }操作类型否则请求会被当作 query 解析看不到 mutation 字段。结语自定义 Mutation 是 PostGraphile v4 中把数据库逻辑与GraphQL API衔接起来的关键机制一个遵守识别规则的 PostgreSQL 函数即可自动变成 Relay 兼容的 mutation 字段配合STRICT、SECURITY DEFINER、pgStrictFunctions和resultFieldName等工具可以精确控制参数的必填性、执行权限与返回字段的语义。本文所有结论均可在当前仓库的 v4 文档、Smart Tags 文档 与 v4 预设源码 中找到对应依据读者可直接对照以上示例在自有数据库中实践。赞分享后端API网关【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址https://gitcode.com/gh_mirrors/cry/crystal点击查看免费下载相关推荐PostGraphile 自定义变更Custom Mutations用 PostgreSQL 函数编写业务级 MutationPostGraphile 自定义变更Custom Mutations用 PostgreSQL 函数编写业务级 Mutation PostGraphile后端API网关PostGraphile v4 自定义变更Custom Mutations实战指南用 PostgreSQL 函数编写精确业务变更PostGraphile v4 自定义变更Custom Mutations实战指南用 PostgreSQL 函数编写精确业务变更 PostGraphile后端API网关PostGraphile v4 自定义查询Custom Queries实战指南用 PostgreSQL 函数自动生成 GraphQL 根字段PostGraphile v4 自定义查询Custom Queries实战指南用 PostgreSQL 函数自动生成 GraphQL 根字段 导读 本文围后端API网关上一篇Apache Kafka 3.1集群监控面板Grafana Dashboard配置下一篇Superfile深度解析现代终端文件管理器的架构设计与实战应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表