I stumbled across an interesting pattern for implementing GraphQL Mutations under their own "namespace", to help keep the Global Namespace neat and tidy. A regular implementation with Apollo would look something like this.
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 */ },
},
};
I decided to try and implement this pattern in a GraphQL API I am building with NestJS, however I seem to be hitting a stumbling block. I have created a TestResolver class, which contains a simple query, along with a namespaced-mutation that should return my nested resolvers.
@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);
}
}
Through some trial and error I managed to get NestJs to successfully build the above code, however I cannot get the nested FieldResolvers to show up.
The plain Apollo implementation of this pattern does seem like it uses some "magic" code to achieve it, so it's definitely possible that the structure of NestJS will not allow me to do something like this. Does anyone have any ideas?
