在NestJS中如何获取GraphQL @Field装饰器配置的name属性值
解决方案
以下是两种可直接落地的实现方案:
方案1:使用@nestjs/graphql内置的元数据存储
@nestjs/graphql内部的TypeMetadataStorage是可以直接调用的,只要你导入的是和项目中依赖版本一致的实例即可,示例代码如下:
// 从项目使用的对应包路径导入元数据存储,此处以常用的@nestjs/graphql搭配type-graphql的code first模式为例 import { getMetadataStorage } from "@nestjs/graphql"; @Resolver() export class MyResolver { constructor(private readonly myService: MyService){} @Query(() => boolean) async prices(@Args('input') input: MyInput){ const metadataStorage = getMetadataStorage(); // 获取MyInput类的所有字段元数据 const inputTypeMetadata = metadataStorage.getInputTypeMetadataByTarget(MyInput); // 匹配TS属性名对应的字段配置 const fieldMetadata = inputTypeMetadata.fields.find(field => field.propertyName === 'priceValue'); // 拿到对外暴露的name值 const gqlFieldName = fieldMetadata?.options?.name; // 此处返回值为"price" } }
如果你的项目用的是mercurius驱动的code first模式,导入路径换成@nestjs/mercurius下的getMetadataStorage即可。
方案2:从GraphQL Schema实例直接读取
你也可以通过@Info()装饰器拿到上下文的GraphQL Schema实例,直接从输入类型定义里读取字段名:
import { Info } from "@nestjs/graphql"; import { GraphQLSchema, GraphQLInputObjectType } from "graphql"; @Resolver() export class MyResolver { constructor(private readonly myService: MyService){} @Query(() => boolean) async prices( @Args('input') input: MyInput, @Info() info: { schema: GraphQLSchema } ){ const inputType = info.schema.getType('MyInput') as GraphQLInputObjectType; const inputFields = inputType.getFields(); // 如需TS属性名转GQL字段名,遍历fields匹配extensions中存储的原始属性名即可 const gqlFieldName = inputFields['price'].name; // 此处返回值为"price" } }
避坑提示
如果之前调用TypeMetadataStorage拿不到值,大概率是你导入的getMetadataStorage来自单独安装的type-graphql包,和@nestjs/graphql内部依赖的版本不是同一个实例,只要统一从@nestjs/graphql包导入即可解决。
内容的提问来源于stack exchange,提问作者Tomas Centeno
相关产品推荐
相关产品推荐

