ARTICLE DETAIL

资讯详情

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

PostGraphile Refs 完全指南:用 @ref 与 @refVia 智能标签为 GraphQL 类型扩展跨表关系

PostGraphile Refs 完全指南:用 @ref 与 @refVia 智能标签为 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 会为数据库中拥有外键约束的两张表自动在 GraphQL Schema 中生成双向关系字段但真实业务往往需要绕路的关系如post - topic - forum的多跳链路或基于多表的多态关系。本文以 PostGraphile 官方文档 refs.md 为主体结合仓库源码完整讲解 Refs 的概念、ref/refVia智能标签的全部参数、路由字符串语法、多态应用与常见陷阱读完后你将能够仅通过 SQL 注释为任意类型声明单数/复数、支持分页的多跳引用字段。Refs 是什么外键关系之外的自定义关系PostGraphile 的核心能力之一是从 PostgreSQL 表结构自动推导 GraphQL 类型与关系。当两张表之间存在外键约束时PostGraphile 会自动在两个方向生成关系字段如Book.author与Person.booksByAuthorId。但自动推导只能覆盖直接外键这一种场景。当你需要穿越多个关系的链路例如post - topic - forum通过多张关联表到达同一个目标表对多个目标表做多态union/interface引用PostGraphile 提供了Refs引用机制。与普通外键关系不同Refs 具有以下特征单向uni-directional声明一个 ref 只会生成一个方向的字段不会自动产生反向字段单数或复数singularref 生成单个对象字段pluralref 生成集合字段复数 ref 同时支持列表list与连接connection接口即既可以通过简单数组返回也可以通过带first/after/condition/orderBy等参数的标准分页连接返回。重要前提Refs 必须建立在真实关系之上Refs 只是路由的声明实际执行仍然依赖 PostgreSQL 外键约束或foreignKey智能标签声明的虚拟约束。官方文档 smart-tags.md 中说明foreignKey的语法形如comment on materialized view my_materialized_view is EforeignKey (key_1, key_2) references other_table (key_1, key_2);如果一个ref声明的via:路由找不到对应的外键关系该 ref 会被静默忽略控制台可能出现如下警告When processing ref for resource posts, could not find matching relation for via:(author_id)-users这意味着先确保底层关系存在真实外键或foreignKey再声明ref。ref 与 refVia两种声明方式ref 智能标签定义 ref 最直接的方式是ref智能标签。它的第一个参数是引用名称随后支持以下可选参数参数含义约束to:目标 GraphQL 类型名当未提供via:时必填from:使用多态时应用该引用的源 GraphQL 类型名可选仅多态场景使用via:到达目标的路由字符串见下文路由字符串可选与to:至少提供其一singular存在即表示这是单数关系与plural互斥plural表示这是复数关系默认值与singular互斥单数 ref 示例来自官方文档通过posts表的author_id引用people表的主键idcomment on table posts is $$ ref author via:(author_id)-people(id) singular $$;singular是标记型参数直接写在标签末尾即可不需要赋值。多路由场景改用 refVia有时候同一个 ref 需要走多条路由可能因为有多张关联表都能到达同一个目标表也可能因为要指向多个不同的目标表。此时不应在ref上写via:而是为每一条路由各写一个refVia标签每个标签由ref 名称 via:组成comment on table books is $$ ref relatedPeople to:Person refVia relatedPeople via:book_authors;people refVia relatedPeople via:book_editors;people $$;上面的例子中Book.relatedPeople会先通过book_authors关联表再到达people也会通过book_editors关联表到达people两条路由的结果合并为同一个Person集合。多目标实现多态Polymorphism当多个refVia指向不同的目标表时就构成了多态引用。例如让log_entries表的author字段在Person与Organization之间二选一comment on table log_entries is $$ ref author to:PersonOrOrganization singular refVia author via:(person_id)-people(person_id) refVia author via:(organization_id)-organizations(organization_id) $$;此时LogEntry.author的类型是PersonOrOrganization。更多多态细节见 多态文档其中还给出了一个实用技巧当源表对每个目标表都只有一条外键时via:可以省略列名使用简写comment on table polymorphic.log_entries is $$ ref author to:PersonOrOrganization singular refVia author via:people refVia author via:organizations $$;路由字符串Route strings语法via:的值是一条由分号;分隔的关系链链中的每一跳表示一次关系跳转。每一跳有以下三种形式形式含义适用条件table_name仅表名当前上下文有且仅有一条外键引用该表直接按该外键跳转(column,...)-table_name本地列列表指向远程表远程目标为该表的主键(column,...)-table_name(column,...)本地列列表指向远程列列表远程目标为指定的列组合不一定是主键多跳示例来自仓库测试 schema kitchen-sink-schema.sql 中的refs场景comment on table books is $$ ref relatedPeople to:Person plural refVia relatedPeople via:(id)-book_authors(book_id);(pen_name_id)-pen_names(id);(person_id)-people(id) refVia relatedPeople via:(id)-book_editors(book_id);(person_id)-people(id) ref editors to:Person plural refVia editors via:(id)-book_editors(book_id);(person_id)-people(id) $$;这条链(id)-book_authors(book_id);(pen_name_id)-pen_names(id);(person_id)-people(id)表达了三跳books.id→book_authors.book_id引用远程列再经pen_names.pen_name_id→ 其id最后经people.person_id→people.id。分号允许跨越多张中间表这正是post - topic - forum式多跳关系的实现基础。仓库源码验证从 SQL 注释到 GraphQL Schema1. 测试 Schema 中的真实用法kitchen-sink-schema.sql 是多态与 refs 的样板间其中既有多目标多态comment on table polymorphic.log_entries is $$ ref author to:PersonOrOrganization singular refVia author via:people refVia author via:organizations $$;也有通过两张不同关联表聚合到同一目标applications的复数 refcomment on table polymorphic.people is $$ unionMember PersonOrOrganization ref applications to:Application refVia applications via:aws_applications refVia applications via:gcp_applications $$;以及穿越三层关联表的链式复数 refvulnerabilities充分印证了路由字符串的三种形式可以混合使用comment on table aws_application_first_party_vulnerabilities is $$ ref owners to:PersonOrOrganization plural refVia owners via:aws_application_first_party_vulnerabilities;aws_applications;people refVia owners via:aws_application_first_party_vulnerabilities;aws_applications;organizations $$;2. 生成出的 GraphQL 类型运行测试后导出的 refs.1.graphql 展示了 ref 字段的最终形态复数 ref 生成标准连接字段支持after、before、condition、first、last、offset、orderBytype Book implements Node { Reads and enables pagination through a set of Person. relatedPeople( after: Cursor first: Int last: Int condition: PersonCondition orderBy: [PeopleOrderBy!] [PRIMARY_KEY_ASC] ): PeopleConnection! }单数 ref 生成单对象字段如Post.author: Person!。多态 ref 的字段类型为联合类型PersonOrOrganization。3. 资源导出与插件扩展点schema/v4/refs.1.export.mjs 中可以看到解析后的智能标签以ref、refVia数组的形式挂在资源resource配置上ref: [relatedPeople to:Person plural, editors to:Person plural], refVia: [ relatedPeople via:(id)-book_authors(book_id);(pen_name_id)-pen_names(id);(person_id)-people(id), relatedPeople via:(id)-book_editors(book_id);(person_id)-people(id), editors via:(id)-book_editors(book_id);(person_id)-people(id), ]同时测试 refs.test.ts 展示了插件可以借助GraphQLObjectType_fields_field钩子中context.scope.pgRefDetails包含codec与refref.paths为解析后的关系路径数组对 ref 字段做二次加工——例如当 ref 路径上每一跳的外键列都不可空时把字段类型从可空升级为GraphQLNonNull。这说明 ref 不仅服务于查询生成也是 Graphile 插件体系的可编程扩展点。常见问题与排查建议ref 字段没有出现在 Schema 中最常见原因是via:路由找不到底层外键。先检查是否真的存在外键约束或已用foreignKey声明虚拟约束再检查控制台是否输出了could not find matching relation for via:...警告。单数还是复数默认是plural想要单数对象字段必须显式加singular。singular与plural不能同时出现。表名简写歧义via:中使用table_name简写时要求当前上下文只有一条外键引用该表若有多个外键指向同一张表必须使用带列名的完整形式(column,...)-table_name(column,...)来消除歧义。多态的目标表列名不同当各目标表列名不一致如person_id与organization_id时必须使用完整的列映射形式不能使用via:people之类的简写。方向是单向的Refs 不会自动生成反向字段。若需要反向关系请为另一张表单独声明对应的 ref或依赖真实外键关系的自动推导。结语Refs 把关系的声明从代码层下沉到了数据库注释层配合ref/refVia智能标签与路由字符串语法PostGraphile 用户可以仅靠 SQL 注释完成多跳链路、多表聚合与多态引用的建模且复数 ref 自动获得完整的分页连接能力。理解Refs 必须建立在真实外键关系之上这一前提并掌握三种路由形式表名简写、列→主键、列→列即可在真实项目中熟练驾驭这一特性。更多智能标签总览可参考 smart-tags.md多态细节可参考 polymorphism.md。赞分享后端API网关【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址https://gitcode.com/gh_mirrors/cry/crystal点击查看免费下载相关推荐PostGraphile V5 Refs 完全指南用 ref / refVia 智能标签为 GraphQL 类型建立跨表关联PostGraphile V5 Refs 完全指南用 ref / refVia 智能标签为 GraphQL 类型建立跨表关联 导读 PostGraphil后端API网关PostGraphile 智能标签文件完全指南使用 postgraphile.tags.json5 定制 GraphQL SchemaPostGraphile 智能标签文件完全指南使用 postgraphile.tags.json5 定制 GraphQL Schema postgraphil后端API网关gs-quant 从零到一卡尔曼滤波价差套利实战gs quant 从零到一卡尔曼滤波价差套利实战 2023 03 07铁矿石单日暴涨 4%螺纹钢 铁矿石的固定布林带价差策略直接打穿止损。把均值换成动态估后端数据库文档数据库创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表