在NestJS / GraphQL请求中获取请求的键的列表

Akx*_*kxe 5 graphql nestjs

我只是在摆弄试图理解,因此我的类型是不准确的。

@Resolver()
export class ProductsResolver {
    @Query(() => [Product])
    async products() {
        return [{
            id: 55,
            name: 'Moonshine',
            storeSupplies: {
                London: 25,
                Berlin: 0,
                Monaco: 3,
            },
        }];
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我要求查询以下数据

{
    products{
      id,
      name,
    }
}
Run Code Online (Sandbox Code Playgroud)

我想async carriers()收到['id', 'name']。我想跳过获取,storeSupplies因为这可能是一个昂贵的SQL调用。


我是GraphQL的新手,我可能错过了一些显而易见的甚至整个模式。提前致谢。

Poo*_*ian 6


基本上你可以单独StoreSupplies查询,以确保在查询产品时不会得到它们。
您还可以在解析器中获取请求的键,然后根据它们进行查询。为此,您可以定义一个参数装饰器,如下所示:

import { createParamDecorator } from '@nestjs/common';

export const Info = createParamDecorator(
  (data, [root, args, ctx, info]) => info,
);

Run Code Online (Sandbox Code Playgroud)

然后在您的解析器中使用它,如下所示:

  @UseGuards(GqlAuthGuard)
  @Query(returns => UserType)
  async getMe(@CurrentUser() user: User, @Info() info): Promise<User> {
    console.log(
      info.fieldNodes[0].selectionSet.selections.map(item => item.name.value),
    );
    return user;
  }
Run Code Online (Sandbox Code Playgroud)

例如,当您运行此查询时

{
  getMe{
    id
    email
    roles
  }
}
Run Code Online (Sandbox Code Playgroud)

console.log输出是:

[ 'id', 'email', 'roles' ]
Run Code Online (Sandbox Code Playgroud)


yah*_*rga 5

另一种选择是直接使用 NestJS 提供的 @Info 装饰器,如下所示:https ://docs.nestjs.com/graphql/resolvers-map#decorators

它可能看起来像这样:

@Resolver()
export class ProductsResolver {
    @Query(() => [Product])
    async products(
    @Info() info
    ) {
        // Method 1 thanks to @pooya-haratian.
        // Update: use this method; read below article to understand why.
        let keys = info.fieldNodes[0].selectionSet.selections.map(item => item.name.value);
        // Method 2 by me, but I'm not sure which method is best.
        // Update: don't use this; read below article to understand why.
        let keys = info.operation.selectionSet.selections[0].selectionSet.selections.map(field => field.name.value);
        return keys;
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:在阅读了关于GraphQL Server Basics: Demystifying the info Argument in GraphQL Resolvers 的这篇文章后,我了解到 fieldNodes 是抽象语法树 (AST) 的摘录,而 operation 是整个查询的 AST 。

至于为什么选择 fieldNodes ( fieldNodes[0])数组中的第一个对象是安全的,这是因为摘录从当前字段开始,而不是查询的根。

因此,@pooya-haratian 的方法是正确的。我只是添加了详细说明并使用了 NestJS 的装饰器 ( @Info)。