Version: legacy

TypeGraphQL Integration

TypeGraphQL is a set of tools that provides you some decorators that can be used for writing your GraphQL definitions. You can define your type definitions and resolvers using TypeScript classes thanks to TypeGraphQL decorators. You can check out TypeGraphQL documents to learn more.

Important: Make sure you follow the installation steps, such as installing reflect-metadata and configuring your typescript correctly.

On the other hand, GraphQL Modules provides encapsulated dependency injection which allows you to seperate your logic from resolvers. It makes testing easy, because you can mock providers and stuff for dependency indejection. You can write standalone modules in a code-first way.

You can import the schema that is generated by TypeGraphQL in your GraphQL Module.

Let's assume we have a Chat type for base fields shared with the entity.

chat.type.ts

import { ObjectType, Field, ID } from 'type-graphql';
@ObjectType()
export class Chat {
@Field((type) => ID)
id: number;
@Field()
title: string;
@Field({ nullable: true })
description?: string;
}

Create another class for our queries and mutations based on this type:

chat.resolver.ts

import { ChatsProvider } from './chats.provider';
import { Resolver, Mutation, Arg, Int, Query } from 'type-graphql';
import { Chat } from './chat.type';
@Resolver((of) => Chat)
export class ChatResolver {
constructor(private chatsProvider: ChatsProvider) {}
@Query((returns) => [Chat])
chats() {
return this.chatsProvider.getChats();
}
@Query((returns) => Chat)
chat(@Arg('id') id: number) {
return this.chatsProvider.getChat(id);
}
@Mutation((returns) => Chat)
createChat(
@Arg('title') title: string,
@Arg('description') description: string
) {
return this.chatsProvider.createChat({
id: Math.random(),
title,
description,
});
}
@Mutation((returns) => Int)
deleteChat(@Arg('id') id: number) {
return this.chatsProvider.deleteChat(id);
}
}

We can use dependency injection of GraphQL Modules in TypeGraphQL. Resolvers and Providers are part of dependency injection in that case.

Then let's create our module:

chat.module.ts

import { GraphQLModule } from '@graphql-modules/core';
import { ChatsProvider } from './chats.provider';
import { buildSchemaSync } from 'type-graphql';
import { ChatResolver } from './chat.resolver';
import { Chat } from './chat.type';
const resolvers = [ChatResolver];
export const ChatsModule = new GraphQLModule({
providers: [ChatsProvider, ...resolvers],
extraSchemas: [
buildSchemaSync({
resolvers,
container: ({ context }) =>
ChatsModule.injector.getSessionInjector(context),
}),
],
});

We have to define resolver classes as providers because they are also part of our dependency injection. container: ({ context }) => ChatsModule.injector.getSessionInjector(context) tells TypeGraphQL to use the ChatsModule dependency injection container for those resolvers.

Check out our example with TypeGraphQL.

Integration with other implementations

You can merge different modules from different implementations like below. So you don't have to use the same implementation method in all modules. GraphQL Modules will handle schema merging for you, even if they are from different implementations.

new GraphQLModule({
imports: [
XModuleCreatedUsingSchemaFirst,
YModuleCreatedUsingNexus,
ZModuleCreatedUsingTypeGraphQL,
],
});