【问题标题】:Implementing 'Namespace-Typed' Resolvers in NestJS + GraphQL在 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 的结构绝对有可能不允许我做这样的事情。有人有什么想法吗?

【问题讨论】:

    标签: typescript graphql nestjs apollo-server


    【解决方案1】:

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

    1. 我创建了根解析器。

    @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
    }
    1. 然后我创建子解析器(用于查询或突变),如下所示:

    @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 };
      }
    }
    1. 所以现在我可以这样查询:user.me 以获取用户详细信息。

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

    【讨论】:

      猜你喜欢
      • 2019-12-23
      • 2019-05-27
      • 2020-05-22
      • 2020-05-03
      • 1970-01-01
      • 2017-08-13
      • 2019-07-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多