后端API网关【免费下载链接】crystal Graphiles Crystal Monorepo; home to Grafast, PostGraphile, pg-introspection, pg-sql2 and much more!项目地址https://gitcode.com/gh_mirrors/cry/crystal点击查看免费下载PostGraphile 会在启动时自动对数据库中被检视的 schema 进行内省并基于其中的表与列生成一整套对应的 GraphQL 类型、查询字段、变更操作与关系字段。本文以app_public.users示例表为主线系统讲解 PostGraphile v5当前仓库postgraphile/postgraphile包对应的版本如何为一张普通 PostgreSQL 表推导出User类型、allUsers连接、userByKey唯一键查询与nodeId查询并深入PgTablesPlugin、PgRBACPlugin等源码说明权限反射RBAC与 unlogged 表的处理原理。读完本文你将能准确预测任意一张表在 PostGraphile 生成的 schema 中会“长出”哪些字段并掌握通过 GRANT/REVOKE 与 smart tags 精细化控制暴露面的方法。一张示例表会生成什么先看文档给出的典型示例表来源tables.mdcreate 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 单数化命名对应 inflection 中的tableType为类型添加列字段如id、username、about、organizationId、isAdmin、createdAt、updatedAt全部以 camelCase 命名添加nodeId字段当表存在主键时生成全局唯一标识字段nodeId详见 node-id.md添加关系字段如organizationByOrganizationId这类外键关系字段详见 relations.md反向关系在相关表类型上添加反向关系字段例如Organization.usersByOrganizationIdCRUD Mutations在根Mutation类型上添加增删改变更操作详见 crud-mutations.mdQuery 字段在根Query类型上添加连接查询、唯一键查询与nodeId查询。文档给出了最终生成在根Query上的字段形态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 }按命名规约生成查询与类型inflector 的作用PostGraphile 的命名并非硬编码而是由可定制的 inflection 系统统一产出。文档中提到的几个关键规约分别是tableType决定表对应的 GraphQL 类型名users→User以及列字段名camelCaseallRows决定连接/列表查询的前缀对应allUsers这类allXxx字段rowByUniqueKeys决定按唯一约束取单行的字段例如userById、userByUsername。这些规约在源码中有清晰对应。在 PgAllRowsPlugin.ts 中allRowsConnection通过build.inflection.allRowsConnection(resource)生成连接字段名而allRowsList生成列表字段名字段描述也会引用build.inflection.tableType(resource.codec)来拼出类型名。也就是说allUsers连接字段的名称、描述与返回类型都源自同一个 inflection 管线。再看唯一键查询。PgRowByUniquePlugin.ts 会枚举表的每个唯一约束unique key将约束中的属性列表如[id]或[username]拼接成语义化字段名并逐一为每个属性生成对应入参id serial primary key与username citext not null unique因此分别推导出userById(id: Int!)与userByUsername(username: String!)。文档中补充说明user(nodeId: ID!)则是通过nodeId取任意行的通用入口由表的全局唯一标识机制提供详见 node-id.md。需要注意的是关系字段名如organizationByOrganizationId在 v5 默认规约下比较冗长。文档提示加载graphile/simplify-inflection插件即可简化这些字段名例如直接使用organization这样的简洁命名。相关最佳实践见 best-practices.md 中对graphile/simplify-inflection的使用说明。连接、过滤与排序是表查询的标准装备allUsers之所以能携带first/last/offset/before/after等游标分页参数、orderBy排序参数与condition过滤参数是因为 PostGraphile 的插件体系为每个表资源默认装配了连接行为连接与分页参数由PgConnectionArgOrderByPlugin、PgFirstLastBeforeAfterArgsPlugin等插件补充遵循 GraphQL Cursor Connections 规范并做了增强如额外的offset参数详见 connections.mdorderBy默认值为[PRIMARY_KEY_ASC]由PgConnectionArgOrderByDefaultValuePlugin注入保证默认行为是按主键升序返回condition: UserCondition由 PgConditionArgumentPlugin.ts 生成类型名基于tableType推导conditionType所有字段按相等条件匹配并取逻辑“与”即文档 filtering.md 中描述的基础过滤能力。在实现层面allRowsConnection与allRowsList分别复用connectionField与listField两条生成路径PgAllRowsPlugin.ts因此连接与列表两种形态共享同一套资源定义与排序/过滤逻辑。权限反射PgRBACPlugin 如何把 GRANT/REVOKE 翻译成 schema文档强调使用PgRBACPlugin时默认开启前提是你没有使用makeV4Preset()的 v4 兼容预设makeV4Preset定义于 v4.tsPostGraphile 只会暴露你实际拥有权限的表、列与字段。举例来说执行GRANT UPDATE (username, name) ON users TO graphql_visitor;之后updateUser变更操作只接受username和name两个字段其余列不会出现在该 mutation 的入参中。其底层原理可以从 PgRBACPlugin.ts 看到该插件被标记为 “Converts the database GRANT/REVOKE privileges to behaviors. Experimental.”即把数据库的 GRANT/REVOKE 权限转换为 PostGraphile 的 behavior行为系统。在pgCodecs_attribute钩子中插件针对每个列与所属表分别计算select/insert/update权限通过entityPermissions查询 ACL再把结果写入属性扩展const canSelect attributePermissions.select || tablePermissions.select; const canInsert attributePermissions.insert || tablePermissions.insert; const canUpdate attributePermissions.update || tablePermissions.update;这正是“列级权限反射进 schema”的实现位置。而 PostgreSQL 侧的角色权限信息来自 utils/pg-introspection 包中的 ACL 内省能力acl.tsexpandRoles会递归展开某个角色被授予的所有角色成员关系含 PUBLIC并尊重NOINHERITaclContainsRole则判断某条 ACL 是否命中当前角色或其继承链上的角色。整个内省结果由PgIntrospectionPlugin通过pgService.pgSettingsForIntrospection注入连接参数后获取PgIntrospectionPlugin.ts。关键行为一个 schema而不是按用户多个 schema需要特别强调文档中的最佳实践结论即使数据库中存在多个不同权限的角色PostGraphile 依然只会生成一个GraphQL schema而不是每个用户一份。具体流程是使用连接字符串中配置的用户身份连接 PostgreSQL遍历该用户在当前数据库中“可以成为”的全部角色即其直接与间接成员角色取所有这些角色权限的并集作为 schema 的暴露面。换句话说schema 暴露的是“你连接的账号在整个角色继承链上能碰到的所有能力”因此文档建议通过pgService.pgSettingsForIntrospection对象来影响内省时的会话设置例如切换role或自定义内省 session 变量从而控制权限并集的边界。该配置项在 dataplan-pg 与 pg.ts 适配器 中均有定义与透传实现。由于暴露面是权限并集文档给出两条配套建议强烈推荐使用PgRBACPlugin它让 schema 更精简不包含你实际用不了的功能强烈建议避免基于列的SELECT授权见 requirements.md列级 SELECT 权限与并集语义配合时容易产生意料之外的暴露更优做法是把不同权限关注点拆分为独立的表再用一对一关系连接。Unlogged 表默认不暴露如何放行PostgreSQL 允许通过CREATE UNLOGGED TABLE创建不写入预写日志WAL的表。出于性能与语义考量PostGraphile 默认不会把 unlogged 表加入 GraphQL schema。这一行为的实现位于 PgTablesPlugin.ts 的unloggedOrTempBehaviors辅助函数当表的持久性被判定为uunlogged或ttemp时它会追加一组负向 behavior[ -resource:select, -resource:connection, -resource:list, -resource:array, -resource:single, -resource:insert, -resource:update, -resource:delete, ]由于这些行为被显式关闭PostGraphile 的 behavior 系统会阻止为该表生成查询、连接、增删改等一切相关字段最终表现为“不出现在 schema 中”。持久性信息来源于pgClass.relpersistence ! p的内省判断PgTablesPlugin.ts。如果确实需要暴露某张 unlogged 表文档给出的方法是通过 smart-tags.md或在源码中直接操作 behavior 扩展显式地为该表赋予所需行为例如补充resource:select等正向行为来覆盖默认的负向行为。behavior 字符串的语法与叠加规则见 behavior.md行为片段用空格分隔、按顺序求值这也是理解“为何 smart tags 可以覆盖默认排除”的关键。小结对 PostGraphile v5 而言一张 PostgreSQL 表在 GraphQL schema 中的“长相”是确定性推导的结果tableType决定类型与字段命名唯一约束决定userByKey系列查询主键决定nodeId连接插件装配分页/排序/过滤PgRBACPlugin按权限并集裁剪暴露面而 behavior 系统统一决定某张表如 unlogged 表是否可见。掌握了这张映射表你就能在写CREATE TABLE之前先在脑海中勾勒出它将生成的完整 GraphQL API。继续深入可阅读仓库中的关联文档relations、connections、filtering、crud-mutations以及pgRBAC相关实现 PgRBACPlugin.ts 与 ACL 工具 acl.ts。赞分享后端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 v5 调试完全指南从 GraphQL 请求、生成 SQL 到 Schema 与性能问题排查PostGraphile v5 调试完全指南从 GraphQL 请求、生成 SQL 到 Schema 与性能问题排查 本文以 PostGraphile v5后端API网关PostGraphile v4 枚举Enums完全指南从 PostgreSQL 类型映射到枚举表、Domain 与 Schema 扩展PostGraphile v4 枚举Enums完全指南从 PostgreSQL 类型映射到枚举表、Domain 与 Schema 扩展 导读 本篇指南聚焦后端API网关上一篇告别繁琐配置Caddy一键迁移工具让Apache/Nginx配置无缝转换下一篇告别静态图表Apache ECharts 动态数据展示完全指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考