Discover how to build efficient, scalable APIs by combining GraphQL with NestJS, the powerful TypeScript framework.
Introduction
Integrating GraphQL with NestJS offers a robust solution for constructing your API. It empowers developers with a strong typing system, modular structure, and the ability to fetch specific data sets. This tutorial will guide you through the setup and usage of GraphQL within a NestJS application.
Setting Up Your Project
First, create a new NestJS project if you haven’t done so already:
npm i -g @nestjs/cli
nestjs new your-project-name
Navigate into your new project directory, and install the necessary GraphQL dependencies:
cd your-project-name
npm install @nestjs/graphql graphql-tools graphql apollo-server-express
Configuring GraphQL
Integrate GraphQL into your NestJS project by importing GraphQLModule
in your application module:
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
@Module({
imports: [
GraphQLModule.forRoot({
autoSchemaFile: 'schema.gql',
// other options here
}),
// other modules here
],
})
export class AppModule {}
In the configuration object of GraphQLModule.forRoot()
, autoSchemaFile
specifies where to generate the schema file. Setting it to a string generates the schema as a file, and setting it to true
generates the schema in memory.
Creating a GraphQL Schema
To get started with schema creation, define your GraphQL types. Create a new TypeScript file for your GraphQL model:
import { ObjectType, Field, ID } from '@nestjs/graphql';
@ObjectType()
export class YourModel {
@Field(() => ID)
id: number;
@Field()
title: string;
// additional fields here...
}
This code snippet defines a basic GraphQL object with an ID and a title field that can be fetched by clients.
Resolvers and Querying Data
Resolvers are essential for handling data retrieval and mutations. To create a resolver, decorate a class with @Resolver()
:
import { Resolver, Query, Args } from '@nestjs/graphql';
import { YourModelService } from './your-model.service';
import { YourModel } from './your-model.model';
@Resolver(() => YourModel)
export class YourModelResolver {
constructor(private yourModelService: YourModelService) {}
@Query(() => [YourModel])
async models(@Args('id', { nullable: true }) id: number) {
return id ? this.yourModelService.findOne(id) : this.yourModelService.findAll();
}
}
The @Query
decorator defines a GraphQL query that can either fetch a single instance or a list of instances, based on the presence of the optional ‘id’ argument.
Handling Mutations
When your application needs to create, update, or delete data, you define mutations. This is similar to a POST, PUT or DELETE request in REST:
import { Resolver, Mutation, Args } from '@nestjs/graphql';
//... Previous imports and code
@Resolver(() => YourModel)
export class YourModelResolver {
// ...Query methods
@Mutation(() => YourModel)
async createModel(@Args('newModelData') newModelData: CreateYourModelInput) {
return this.yourModelService.create(newModelData);
}
}
Here, the @Mutation
decorator indicates a mutation method which will handle the creation of new records.
Subscriptions
NestJS and GraphQL can also handle real-time data updates using subscriptions. To implement a subscription, adapt your resolver accordingly:
import { Resolver, Subscription, Args } from '@nestjs/graphql';
import { PubSub } from 'graphql-subscriptions';
const pubSub = new PubSub();
@Resolver(() => YourModel)
export class YourModelResolver {
// ...Query and Mutation methods
@Subscription(() => YourModel)
modelAdded() {
return pubSub.asyncIterator('modelAdded');
}
// Trigger this in Mutation actions when a model is added:
// pubSub.publish('modelAdded', { modelAdded: model });
}
The @Subscription
decorator indicates a GraphQL subscription. The PubSub class offers a way to publish and listen to events for real-time updates.
Conclusion
The amalgamation of GraphQL and NestJS provides an efficient and modern approach to building APIs. Following this tutorial, you should now have a foundational understanding of setting up and using GraphQL within a NestJS application for your upcoming projects.