You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:03:36