GraphQL with NestJS

Integrating GraphQL into a NestJS application using Apollo Server or other GraphQL libraries.


GraphQL and NestJS

Introduction to GraphQL and NestJS

This document provides an introduction to GraphQL and NestJS, exploring their individual benefits and how they can be effectively combined to build robust and efficient APIs.

Overview of GraphQL and NestJS

GraphQL

GraphQL is a query language for your API and a server-side runtime for executing those queries by using a type system you define for your data. GraphQL provides a complete and understandable description of the data in your API, giving clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

Benefits of GraphQL:

  • Efficient Data Fetching: Clients request only the data they need, reducing over-fetching.
  • Strongly Typed Schema: Provides clarity and predictability in API interactions.
  • Single Endpoint: Simplifies API management and reduces complexity.
  • Real-time Capabilities: Supports subscriptions for real-time updates.
  • Introspection: Allows clients to discover the API schema easily.

NestJS

NestJS is a progressive Node.js framework for building efficient, reliable and scalable server-side applications. It uses modern JavaScript, is built with TypeScript (preserves compatibility with pure JavaScript) and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).

Benefits of NestJS:

  • Modular Architecture: Organizes applications into reusable modules.
  • Dependency Injection: Improves code testability and maintainability.
  • TypeScript Support: Provides static typing and enhances code quality.
  • Built-in CLI: Simplifies project scaffolding and development tasks.
  • Extensible: Integrates seamlessly with various libraries and frameworks.

How GraphQL and NestJS Complement Each Other

NestJS provides a solid foundation for building GraphQL APIs. Its modular architecture, dependency injection, and TypeScript support make it an excellent choice for managing the complexity of GraphQL implementations. NestJS simplifies the process of integrating GraphQL libraries like Apollo Server or Mercurius, allowing developers to focus on defining the API schema and resolvers. Together, they allow building maintainable, testable, and scalable APIs.

  • NestJS handles the underlying server infrastructure and request lifecycle.
  • GraphQL defines the API schema and resolvers for data fetching.
  • NestJS's dependency injection makes it easy to manage data sources and business logic within the GraphQL resolvers.

Setting up a Basic NestJS Project

These instructions outline how to set up a basic NestJS project with the Nest CLI and integrate GraphQL.

Prerequisites

  • Node.js (>= 16.x)
  • npm or yarn

Installation

  1. Install Nest CLI globally:
    npm install -g @nestjs/cli
  2. Create a new NestJS project:
    nest new my-graphql-app

    Choose your preferred package manager (npm, yarn, pnpm).

  3. Navigate to the project directory:
    cd my-graphql-app

Integrating GraphQL

  1. Install GraphQL dependencies:
    npm install @nestjs/graphql @nestjs/apollo graphql apollo-server-express
  2. Modify the app.module.ts file:
     import { Module } from '@nestjs/common';
    import { GraphQLModule } from '@nestjs/graphql';
    import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
    
    @Module({
      imports: [
        GraphQLModule.forRoot<ApolloDriverConfig>({
          driver: ApolloDriver,
          autoSchemaFile: 'schema.gql', // Schema will be generated automatically
          sortSchema: true,           // Sort the schema for consistency
          playground: true,           // Enable the GraphQL playground in development
          debug: true,                // Enable debugging information
        }),
      ],
      controllers: [],
      providers: [],
    })
    export class AppModule {} 
  3. Create a GraphQL type (e.g., src/user/user.type.ts):
     import { ObjectType, Field, ID } from '@nestjs/graphql';
    
    @ObjectType()
    export class User {
      @Field(() => ID)
      id: string;
    
      @Field()
      firstName: string;
    
      @Field()
      lastName: string;
    
      @Field()
      email: string;
    } 
  4. Create a resolver (e.g., src/user/user.resolver.ts):
     import { Resolver, Query, Args, ID } from '@nestjs/graphql';
    import { User } from './user.type';
    
    @Resolver(() => User)
    export class UserResolver {
      // Simulated user data (replace with database connection)
      private users: User[] = [
        { id: '1', firstName: 'John', lastName: 'Doe', email: 'john.doe@example.com' },
        { id: '2', firstName: 'Jane', lastName: 'Smith', email: 'jane.smith@example.com' },
      ];
    
      @Query(() => [User], { name: 'users' })
      getAllUsers(): User[] {
        return this.users;
      }
    
      @Query(() => User, { name: 'user' })
      getUser(@Args('id', { type: () => ID }) id: string): User {
        return this.users.find(user => user.id === id);
      }
    } 
  5. Register the resolver in app.module.ts:
     import { Module } from '@nestjs/common';
    import { GraphQLModule } from '@nestjs/graphql';
    import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
    import { UserResolver } from './user/user.resolver'; // Import the resolver
    
    @Module({
      imports: [
        GraphQLModule.forRoot<ApolloDriverConfig>({
          driver: ApolloDriver,
          autoSchemaFile: 'schema.gql',
          sortSchema: true,
          playground: true,
          debug: true,
        }),
      ],
      controllers: [],
      providers: [UserResolver], // Add the resolver to the providers array
    })
    export class AppModule {} 
  6. Run the application:
    npm run start:dev
  7. Access the GraphQL playground:

    Open your browser and navigate to http://localhost:3000/graphql to interact with the GraphQL API.