Quick Start
GraphQL is a new way of thinking about the APIs. Here's a great
comparison between GraphQL and REST. In this set of articles, I'm not gonna explain what the GraphQL is, but rather
show how to work with the dedicated
@nestjs/graphql module.
The
GraphQLModule is nothing more than a wrapper around the
Apollo server. We don't reinvent the wheel but provide a ready to use a module instead, that brings a clean way to
play with the GraphQL and Nest together.
Installation
Firstly, we need to install the required packages:
$ npm i --save @nestjs/graphql apollo-server-express graphql-tools graphql
Apollo Middleware
Once the packages are installed, we can apply the GraphQL middleware provided by the
apollo-server-express package:
import {
Module,
MiddlewaresConsumer,
NestModule,
RequestMethod,
} from '@nestjs/common';
import { graphqlExpress } from 'apollo-server-express';
import { GraphQLModule } from '@nestjs/graphql';
@Module({
imports: [GraphQLModule],
})
export class ApplicationModule implements NestModule {
configure(consumer: MiddlewaresConsumer) {
consumer
.apply(graphqlExpress(req => ({ schema: {}, rootValue: req })))
.forRoutes({ path: '/graphql', method: RequestMethod.ALL });
}
}
import { Module, RequestMethod } from '@nestjs/common';
import { graphqlExpress } from 'apollo-server-express';
import { GraphQLModule } from '@nestjs/graphql';
@Module({
imports: [GraphQLModule],
})
export class ApplicationModule {
configure(consumer) {
consumer
.apply(graphqlExpress(req => ({ schema: {}, rootValue: req })))
.forRoutes({ path: '/graphql', method: RequestMethod.ALL });
}
}
That's all. We passed an empty object as a GraphQL schema and req (request object) as a rootValue for now.
Additionally, there're a few other available graphqlExpress options and you can read about them here.
Schema
To create a schema, we are using GraphQLFactory which is a part of the @nestjs/graphql package.
This component provides a createSchema() method that accepts the same object as a makeExecutableSchema() function, well-described here.
The schema options object demand at least resolvers and the typeDefs property.
You can pass type definitions manually, or use a utility mergeTypesByPaths() method of the GraphQLFactory.
Let's have a look on the following example:
import {
Module,
MiddlewaresConsumer,
NestModule,
RequestMethod,
} from '@nestjs/common';
import { graphqlExpress } from 'apollo-server-express';
import { GraphQLModule, GraphQLFactory } from '@nestjs/graphql';
@Module({
imports: [GraphQLModule],
})
export class ApplicationModule implements NestModule {
constructor(private readonly graphQLFactory: GraphQLFactory) {}
configure(consumer: MiddlewaresConsumer) {
const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
const schema = this.graphQLFactory.createSchema({ typeDefs });
consumer
.apply(graphqlExpress(req => ({ schema, rootValue: req })))
.forRoutes({ path: '/graphql', method: RequestMethod.ALL });
}
}
import { Module, RequestMethod } from '@nestjs/common';
import { graphqlExpress } from 'apollo-server-express';
import { GraphQLModule, GraphQLFactory } from '@nestjs/graphql';
@Dependencies(GraphQLFactory)
@Module({
imports: [GraphQLModule],
})
export class ApplicationModule {
constructor(graphQLFactory) {
this.graphQLFactory = graphQLFactory;
}
configure(consumer) {
const typeDefs = this.graphQLFactory.mergeTypesByPaths('./**/*.graphql');
const schema = this.graphQLFactory.createSchema({ typeDefs });
consumer
.apply(graphqlExpress(req => ({ schema, rootValue: req })))
.forRoutes({ path: '/graphql', method: RequestMethod.ALL });
}
}
Hint Learn more about GraphQL schema here.
In this case, the GraphQLFactory will go through each directory, and merge files that have a .graphql extension.
Afterwards, we can create a schema using these particular type definitions. The resolvers will be reflected automatically.
Here you can read more about what the resolvers map actually is.