如何在Postgraphile插件中基于上下文添加自定义where条件?
Postgraphile全局添加隐式WHERE条件实现方案
你要的基于上下文动态给所有查询加隐式WHERE条件的需求,可以直接通过Postgraphile原生提供的钩子机制实现,完全不需要依赖数据库层的RLS策略,所有逻辑都可以在Node.js层处理。
1. 最简实现:全局pgQuery钩子
这是最贴合你期望写法的方案,直接在Postgraphile配置中注册pgQuery钩子,即可在所有SQL查询生成前拿到queryBuilder实例,直接拼接条件:
const postgraphile = require('postgraphile').postgraphile; const app = express(); app.use( postgraphile(process.env.DATABASE_URL, 'public', { // 其余常规配置 hooks: { pgQuery: (queryBuilder, context, build) => { const { sql } = build; // 从解析上下文拿到user_id,和你自己的上下文字段对应即可 const currentUserId = context.user_id; if (currentUserId) { // 和你期望的写法完全一致,直接加WHERE条件 queryBuilder.where(sql.query`user_id = ${sql.value(currentUserId)}`); } } } }) );
注意:如果需要适配多表场景,部分表没有
user_id字段的话,可以通过queryBuilder.getTable()拿到当前查询对应的表元信息,判断字段存在后再加条件,避免SQL报错。
2. 更灵活的分表配置方案
如果不同表需要加的全局条件不一样,或者只需要给部分表加条件,可以用官方graphile-utils提供的makeAddPgTableConditionPlugin批量生成规则:
const { makeAddPgTableConditionPlugin, makePluginByCombiningPlugins } = require('graphile-utils'); // 给单表加全局条件的插件 const userTableConditionPlugin = makeAddPgTableConditionPlugin( 'public', // 表所在的schema名 'orders', // 要加条件的表名 (build) => { const { sql } = build; return (context) => { const userId = context.user_id; if (!userId) return null; return sql.query`creator_id = ${sql.value(userId)}`; }; } ); // 可以给每个表单独配置规则,最后合并所有插件传入Postgraphile即可 const globalConditionPlugins = makePluginByCombiningPlugins( userTableConditionPlugin, // 其他表的条件插件依次放入 ); // 初始化Postgraphile时传入插件 app.use(postgraphile(process.env.DATABASE_URL, 'public', { appendPlugins: [globalConditionPlugins], // 其余配置 }));
两种方案都支持写任意复杂的Node层业务逻辑,包括动态判断权限、拼接多条件组合等场景,不用修改数据库侧的任何配置。
内容的提问来源于stack exchange,提问作者Faizuddin Mohammed
相关产品推荐
相关产品推荐

