如何让TypeGraphQL生成的复数查询强制携带tenantId字段的Where子句?
TypeGraphQL强制复数查询携带tenantId条件的实现方案
一、不用自定义解析器行不行?
不行。TypeGraphQL自动生成的CRUD查询(比如默认的users列表查询),参数都是可选的,框架本身没有内置规则来约束Where子句必须包含特定字段,所以没法直接通过配置实现这个强制校验。
二、自定义解析器的两种实现方式
1. 手动重写查询解析器,直接校验参数
把自动生成的users查询替换成自己写的解析器,在方法里直接检查where参数是否包含tenantId:
import { Query, Arg } from "type-graphql"; import { User } from "./entities/User"; import { UserWhereInput } from "./generated/type-graphql"; // 复用自动生成的Where输入类型 @Resolver(User) export class UserResolver { @Query(() => [User]) async users( @Arg("where", () => UserWhereInput) where: UserWhereInput ) { // 强制校验:必须传入tenantId相关条件 if (!where.tenantId) { throw new Error("查询users必须携带tenantId条件"); } // 替换为你的实际数据库查询逻辑,比如TypeORM的find方法 return User.find({ where }); } }
2. 用全局中间件统一处理多查询
如果多个复数查询(比如posts、comments)都需要这个规则,写个全局中间件批量校验,不用每个解析器重复写逻辑:
import { MiddlewareFn } from "type-graphql"; // 定义需要校验tenantId的查询列表 const NEED_TENANT_QUERIES = ["users", "posts", "comments"]; export const RequireTenantId: MiddlewareFn = async ({ args, info }, next) => { if (NEED_TENANT_QUERIES.includes(info.fieldName)) { const whereArgs = args.where; // 检查是否携带tenantId条件 if (!whereArgs?.tenantId) { throw new Error(`查询${info.fieldName}必须携带tenantId条件`); } } return next(); };
然后在构建Schema时注册这个中间件:
import { buildSchema } from "type-graphql"; import { RequireTenantId } from "./middlewares/RequireTenantId"; import { UserResolver, PostResolver } from "./resolvers"; const schema = await buildSchema({ resolvers: [UserResolver, PostResolver], globalMiddlewares: [RequireTenantId], });
额外小建议
- 要是和TypeORM配合使用,数据库层面可以加备份约束,但业务逻辑校验还是在GraphQL层做更直接,用户能立刻得到错误反馈。
- 可以把校验逻辑封装成通用函数,比如
checkTenantIdExists(where: any),用到时直接调用,减少重复代码。
内容的提问来源于stack exchange,提问作者Vinay Gupta
相关产品推荐
相关产品推荐

