在 NestJS + GraphQL 中实现“命名空间类型”解析器

Posted

技术标签:

【中文标题】在 NestJS + GraphQL 中实现“命名空间类型”解析器【英文标题】:Implementing 'Namespace-Typed' Resolvers in NestJS + GraphQL 【发布时间】:2020-12-30 02:19:47 【问题描述】:

我偶然发现了 interesting pattern 在他们自己的“命名空间”下实现 GraphQL 突变,以帮助保持全局命名空间整洁。 Apollo 的常规实现看起来像这样。

const typeDefs = gql`
type Mutation 
    article: ArticleMutations
  

  type ArticleMutations 
    like: Boolean
    unlike: Boolean
  
`;

const resolvers = 
  Mutation: 
    article: () => (), // ✨✨✨ magic! which allows to proceed call of sub-methods
  
  ArticleMutations: 
    like: () =>  /* resolver code */ ,
    unlike: () =>  /* resolver code */ ,
  ,
;

我决定尝试在我用 NestJS 构建的 GraphQL API 中实现这种模式,但是我似乎遇到了一个绊脚石。我创建了一个 TestResolver 类,其中包含一个简单的查询,以及一个应该返回我的嵌套解析器的命名空间突变。

@ObjectType()
export class TestMutations 
  constructor(private readonly _testService: TestService) 

  @Field(() => String)
  test: string;

  @ResolveField(() => Unit, )
  async create(@Args('input') input: CreateTestInput): Promise<Test> 
    try 
      return await this._testService.create(input);
     catch (err) 
      this._logger.error(err);
      throw new HttpException('An error occurred when creating the Test', HttpStatus.INTERNAL_SERVER_ERROR);
    
  


@Resolver(() => Test)
export class TestResolver 
  constructor(private readonly _testService: UnitService) 

  @Query(() => Test,  name: 'test', nullable: true )
  async getTest(@Args('id') id: Id): Promise<Test> 
    try 
      return await this._testService.get(id);
     catch (err) 
      this._logger.error(err);
      throw new HttpException('An error occurred when fetching the Test', HttpStatus.INTERNAL_SERVER_ERROR);
    
  

  @Mutation(() => TestMutations)
  test(): TestMutations 
    return new TestMutations(this._testService);
  

通过反复试验,我设法让 NestJs 成功构建了上述代码,但是我无法让嵌套的 FieldResolvers 显示出来。

这种模式的普通 Apollo 实现确实似乎使用了一些“神奇”的代码来实现它,所以 NestJS 的结构绝对有可能不允许我做这样的事情。有人有什么想法吗?

【问题讨论】:

【参考方案1】:

您也可以使用 Nest.js 做到这一点。我是怎么做到的:

    我创建了根解析器。

@Resolver('root')
export class RootResolver 
  @Query((returns) => KBQuery,  name: 'kb' )
  kbQuery() 
    return new KBQuery();
  

  @Query((returns) => UserQuery,  name: 'user' ) // Here can be @Mutation
  userQuery() 
    return new UserQuery();
  
  // ... Other root Queries and Mutations here
    然后我创建子解析器(用于查询或突变),如下所示:

@ObjectType()
export class UserQuery 

@Resolver((of) => UserQuery)
export class UserQueryResolver 
  @ResolveField((returns) => UserMyPayload)
  async me(@Context('req')  currentUser : Request) 
    if (!currentUser) return  error: new ApiError('unauthorized', 'Authorization required') ;

    return  user: currentUser.user ;
  
    所以现在我可以这样查询:user.me 以获取用户详细信息。

我希望使用 Nest.js 更容易。所以来自 Nest 的人需要在 @Query/@Mutation 属性中添加一些东西。

【讨论】:

以上是关于在 NestJS + GraphQL 中实现“命名空间类型”解析器的主要内容,如果未能解决你的问题,请参考以下文章

NestJS Graphql webpack 生产构建错误

NestJS 5 GraphQL 错误查询在解析器中定义,但不在模式中

无法在 GraphQL 中实现联合

在graphql中实现多个接口

是否可以在 GraphQL 中实现多个接口?

在 GraphQL 服务器中实现访问控制的好模式是啥?