ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

PostGraphile 表自动映射指南:从 PostgreSQL 表到 GraphQL Schema 的完整生成机制

PostGraphile 表自动映射指南:从 PostgreSQL 表到 GraphQL Schema 的完整生成机制 后端API网关【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址https://gitcode.com/gh_mirrors/cry/crystal点击查看免费下载本指南聚焦 PostGraphile 的核心能力之一基于数据库内被检视introspected的表与列自动向生成的 GraphQL Schema 中注入一系列元素——包括表类型、列字段、关系字段、全局唯一标识、CRUD Mutations 与根查询字段。读完本文你将掌握 PostGraphile 对一张 PostgreSQL 表的完整翻译规则、每个自动生成元素背后的插件与 inflector 机制以及如何通过权限RBAC与 behaviors 精确控制这些元素是否出现在最终 Schema 中。一、表驱动的 Schema 生成总览PostGraphile 会在启动时对配置的 PostgreSQL schema 进行 introspection结构检视并把检视到的表、列、约束、外键等信息映射为 GraphQL 类型与字段。以下面这张典型的users表为例create table app_public.users ( id serial primary key, username citext not null unique, name text not null, about text, organization_id int not null references app_public.organizations on delete cascade, is_admin boolean not null default false, created_at timestamptz not null default now(), updated_at timestamptz not null default now() );对这样一张表PostGraphile 会依次生成目标位置生成内容新增 GraphQL 类型名为User的对象类型UpperCamelCase 且单数化并为每个列添加 camelCase 字段id、username、about、organizationId、isAdmin、createdAt、updatedAt等若表有主键则额外添加nodeId全局唯一标识字段类型内关系字段由外键推导出的前向关系字段例如organizationByOrganizationId相关表类型反向关系字段例如在Organization类型上添加usersByOrganizationId根Mutation类型针对该表的 CRUD MutationsCreate / Update / Delete根Query类型allUsers连接字段支持分页、过滤、排序每个唯一约束对应一个userByKey(key: ...)字段如userById、userByUsername以及按nodeId取行的user(nodeId: ID!)字段注意上述organizationByOrganizationId、usersByOrganizationId这类冗长命名可以通过加载graphile/simplify-inflection插件来简化详见本文简化关系命名一节。二、表到 GraphQL 类型命名与列字段PostGraphile 将表名转换为 GraphQL 类型名时使用UpperCamelCase 单数化规则对应 inflectortableTypeusers→User。列名则被转换为camelCaseorganization_id→organizationId、created_at→createdAt列字段的类型由其 PostgreSQL 数据类型映射而来。在源码层面这套机制由graphile-build-pg中的PgBasicsPlugin、PgTablesPlugin、PgAttributesPlugin等插件协同完成它们被统一编排进 PostGraphile 的默认 preset 中。你可以在本仓库的 amber preset 定义 中看到这些插件的完整加载顺序export const orderedPlugins: GraphileConfig.Preset { plugins: [ QueryQueryPlugin, PgBasicsPlugin, PgCodecsPlugin, PgTypesPlugin, PgIntrospectionPlugin, PgTablesPlugin, AddNodeInterfaceToSuitableTypesPlugin, NodePlugin, PgAllRowsPlugin, PgRowByUniquePlugin, PgAttributesPlugin, MutationPayloadQueryPlugin, PgRelationsPlugin, PgMutationCreatePlugin, PgMutationUpdateDeletePlugin, PgCustomTypeFieldPlugin, NodeAccessorPlugin, // ... ], };从代码结构可以看出PgTablesPlugin负责把检视到的表注册为可用的数据资源PgAttributesPlugin负责把列展开为类型字段PgRelationsPlugin负责关系字段而PgAllRowsPlugin、PgRowByUniquePlugin、NodeAccessorPlugin则分别对应根查询上的allUsers、userByKey与user(nodeId:)字段。三、nodeId全局唯一对象标识只要表包含主键PostGraphile 就会为其类型添加一个nodeId在新版 amber preset 中表现为id字段遵循 GraphQL Global Object Identification Specification即业界常说的 Relay 全局对象标识规范。这为客户端提供了一种不依赖具体业务键的、跨类型稳定的对象寻址方式。不同 preset 对全局唯一标识的处理有所差异postgraphile/presets/amber默认给每个带主键的表分配全局唯一标识并将其暴露为名为id的属性若表本身已有一个名为id的列则把该列重命名为rowId以避免冲突postgraphile/presets/relay彻底隐藏裸主键在整个 Schema包括查询、变更、过滤、函数入参中统一使用全局对象标识V4 preset沿用 PostGraphile V4 的nodeId命名习惯。关于id/rowId/nodeId的取舍、specFromNodeId()解码辅助函数以及在函数入参中使用argNvariant nodeId的完整讨论请参阅 node-id 文档。四、关系字段的自动发现PostGraphile 通过检视表上的外键约束来自动发现关系并在 Schema 中注入两类字段前向关系在当前类型上为每个外键添加指向目标表的字段如User.organizationByOrganizationId命名规则为目标类型 源字段的 camelCase 组合inflectorssingleRelationByKeys、singleRelationByKeysBackwards、manyRelationByKeys反向关系在目标表类型上添加指向当前表的字段如Organization.usersByOrganizationId。一对多、多对一、一对一关系都会被自动识别多对多关系通常需要借助社区插件或通过返回setof的计算列处理详见 relations 文档。非唯一约束暴露为支持分页、过滤 与排序的 connection唯一约束则直接暴露表类型本身。简化关系命名默认的关系字段名如organizationByOrganizationId虽然无歧义但较为冗长。文档中特别提醒这些字段可以通过加载graphile/simplify-inflection插件来简化例如把organizationByOrganizationId简化为organization、把usersByOrganizationId简化为users。五、CRUD Mutations 的自动生成对于具备相应数据库权限的表PostGraphile 会自动在根Mutation类型上生成 CRUD MutationsCreate / Read / Update / Delete 中的 CUD 部分。以上述users表为例典型会得到createUser—— 创建单个UserupdateUser/updateUserById/updateUserByUsername—— 通过全局唯一 id 或唯一键更新单个UserdeleteUser/deleteUserById/deleteUserByUsername—— 通过全局唯一 id 或唯一键删除单个User。update与delete类 Mutation 仅在表包含primary key列时才会生成createMutation 则不受此限制。源码层面这些能力来自PgMutationCreatePlugin与PgMutationUpdateDeletePlugin见 amber preset。如果你想禁用 CRUD Mutations例如改为全部使用自定义 mutation可以在 preset 中设置schema.defaultBehavior: -insert -update -delete更多设计建议与排查指南如mutation 没出现的常见原因请参考 crud-mutations 文档。六、Query 类型allUsers、userByKey 与 user(nodeId)在根Query类型上PostGraphile 为每张表生成三类查询字段type Query implements Node { allUsers( first: Int last: Int offset: Int before: Cursor after: Cursor orderBy: [UsersOrderBy!] [PRIMARY_KEY_ASC] condition: UserCondition ): UsersConnection userById(id: Int!): User userByUsername(username: String!): User user(nodeId: ID!): User }allUsers返回一个UsersConnection内置游标分页first/last/before/after、偏移分页offset、排序orderBy与条件过滤condition默认按主键升序PRIMARY_KEY_ASC排列inflectorallRows由PgAllRowsPlugin提供userById/userByUsername表上每个唯一约束对应一个userByKey(key: ...)字段用唯一键直接取单行inflectorrowByUniqueKeys由PgRowByUniquePlugin提供user(nodeId: ID!)按全局唯一nodeId取单行由NodeAccessorPlugin提供。连接connection遵循 Relay 游标连接规范并附加了totalCount、nodes跳过 edge 包装、PageInfo.startCursor/endCursor等增强特性如果你更偏好简单列表而非连接可以通过 behaviors 配置defaultBehavior: -connection list来切换详见 connections 文档 与 behavior 文档。七、权限PgRBACPlugin 与 Schema 最小化如果你使用PgRBACPlugin在非makeV4Preset()场景下默认启用PostGraphile 只会暴露你实际拥有权限的表、列与字段。例如执行GRANT UPDATE (username, name) ON users TO graphql_visitor;那么生成的updateUserMutation 将只接受username和name字段——其余列不会出现在输入类型中。PgRBACPlugin的工作机制是检视数据库中的 RBACGRANT / REVOKE权限并将其映射进 GraphQL Schema。需要强调的是按照 GraphQL 最佳实践它仍然只生成一个统一的 Schema而非按用户分别生成具体做法是以连接字符串中使用的 PostgreSQL 用户为起点遍历该用户在数据库内可以变身为become的所有角色取这些角色权限的并集作为 Schema 的暴露边界。你可以通过pgService.pgSettingsForIntrospection对象影响检视阶段使用的设置。该配置项在源码中由 dataplan-pg 的makePgService解析并挂载到PgServiceConfiguration上pgSettingsForIntrospection会随 introspection 连接一并发送相关类型声明位于 dataplan-pg 的接口定义。使用PgRBACPlugin是官方推荐做法因为它能产出精简得多的 Schema——不包含你实际上无法使用的功能从而降低 Schema 体积与误用风险。关于列级 SELECT 授权的建议文档中有一则重要提示强烈不建议对列使用基于列的SELECTGRANT详见 requirements 文档。更推荐的做法是把不同的权限关注点拆分到独立的表中再通过一对一关系进行关联从而让 RBAC 以表为粒度自然生效。八、Unlogged 表默认不暴露如果数据库中存在通过CREATE UNLOGGED TABLE创建的unlogged 表其数据不写入 WAL 日志崩溃后不保证持久PostGraphile 默认不会将其加入 GraphQL Schema。你可以在本仓库的测试 Schema 中看到相关示例——kitchen-sink-schema.sql 定义了一张c.unlogged表用于验证这一行为。如需覆盖该默认行为可以显式地通过 smart tags 或类似方式为这张 unlogged 表赋予所需的 behaviors从而使其重新进入 Schema。九、延伸阅读围绕表自动映射这一主题以下仓库文档与本指南直接相关可作为下一步深入的方向relations外键如何驱动关系字段含一对多、多对多示例connections连接的分页语义、totalCount/nodes增强与列表切换filteringcondition参数、索引约束与高级过滤插件crud-mutationsCRUD Mutation 的字段清单、示例与排查清单node-id全局唯一标识的 preset 差异与解码方式behavior 与 smart-tags通过 behaviors 与智能标签精确控制每个元素的暴露与形态。赞分享后端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 生成指南从 PostgreSQL 表到自动化的查询、连接与 CRUDPostGraphile 表驱动的 GraphQL Schema 生成指南从 PostgreSQL 表到自动化的查询、连接与 CRUD PostGraphil后端API网关PostGraphile v4 枚举Enums完全指南从 PostgreSQL 类型映射到枚举表、Domain 与 Schema 扩展PostGraphile v4 枚举Enums完全指南从 PostgreSQL 类型映射到枚举表、Domain 与 Schema 扩展 导读 本篇指南聚焦后端API网关PostGraphile 5 完全指南从 PostgreSQL 自动生成高性能、可深度定制的 GraphQL APIPostGraphile 5 完全指南从 PostgreSQL 自动生成高性能、可深度定制的 GraphQL API PostGraphile 是 Graph后端API网关创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表