How to Use GraphQL with NestJS

Updated: December 31, 2023 By: Guest Contributor Post a comment

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.