我只是想弄明白,所以我的类型不正确。
@Resolver()
export class ProductsResolver {
@Query(() => [Product])
async products() {
return [{
id: 55,
name: 'Moonshine',
storeSupplies: {
London: 25,
Berlin: 0,
Monaco: 3,
},
}];
}
}
如果我在查询以下请求数据
{
products{
id,
name,
}
}
我希望async carriers()
收到['id', 'name']
。我想跳过storeSupplies
的获取,因为这可能是一个昂贵的SQL调用。
我是GraphQL的新手,我可能错过了一些显而易见的甚至整个模式。预先感谢。
答案 0 :(得分:3)
基本上,您可以分隔StoreSupplies
个查询,以确保在对产品进行查询时不会得到它们。
您还可以在解析器中获取请求的密钥,然后根据它们进行查询。为此,您可以定义一个参数修饰符,如下所示:
import { createParamDecorator } from '@nestjs/common';
export const Info = createParamDecorator(
(data, [root, args, ctx, info]) => info,
);
然后像下面这样在解析器中使用它:
@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;
}
例如,当您运行此查询时
{
getMe{
id
email
roles
}
}
console.log
的输出是:
[ 'id', 'email', 'roles' ]
答案 1 :(得分:3)
另一种选择是直接使用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;
}
}
更新:阅读GraphQL Server Basics: Demystifying the info Argument in GraphQL Resolvers上的这篇文章后,我了解到fieldNodes是抽象语法树(AST)的摘录,而操作是的AST整个查询。
关于为什么安全地选择fieldNodes(fieldNodes[0]
)数组中的第一个对象的原因,是因为摘录从当前字段开始,而不是查询的根。
因此,@ pooya-haratian的方法是正确的。我只是添加了详细说明,并使用了NestJS的装饰器(@Info
)。