How YOU can use Nest to build a GraphQL API
Tags: tutorial, javascript, graphql, webdev
Published: 2019-06-26 20:40:50

---
title: How YOU can use Nest to build a GraphQL API
published: true
description: How YOU can use Nest to build a graphql API
tags: tutorial, javascript, graphql, webdev
cover_image: https://thepracticaldev.s3.amazonaws.com/i/vvdbqoo6bt92vmo71h33.jpg
---
Follow me on [Twitter](https://twitter.com/chris_noring), happy to take your suggestions on topics or improvements /Chris

> There are many ways to build a GraphQL API. Looking at JavaScript you might be using the raw `grapql` library, the `graphql-express` library or why not the one from [apollo](https://www.apollographql.com/). There is another really great way and that is Nest.js that nicely integrates with GraphQL 

In this article we will:

- **Explain** GraphQL fundamentals quickly. We will explain enough for you to understand the major constructs.
- **Create** a first Nest.js + GraphQL project and see what a full CRUD looks like
- **Best practices** let's see what we can do to leverage the full power of Nest 

## GraphQL fundamentals
I've explained the fundamentals of Graphql in the following articles:

- [GraphQL with Node.js and Express](https://dev.to/azure/building-a-graphql-server-with-nodejs-andexpress-5hfh)
- [GraphQL with Node.js + Apollo](https://dev.to/azure/creating-a-graphql-server-withapollo-jjj)

This article would be crazy long if we added a full primer to GraphQL so let's be happy by stating a GraphQL API consist of a schema and resolver functions.

## Create your first `Hello GraphQL` in Nest.js
Ok, now we have a basic understanding of how GraphQL works. It's time to do the following:

1. **Scaffold** a Nest project
2. **Wire up** the project to use GraphQL
3. **Write** our schema and resolvers

### Scaffold a Nest.js project
To scaffold a new project just type the following:

```
nest new hello-world
```

You can replace `hello-world` with the name of your project. This will give you the needed files for our next step, which is to add GraphQL.

### Wire up GraphQL

Now to use GraphQL in the project we just created we need to do the following:

1. install the needed dependencies
2. Configure the `GraphQLModule`

Ok, to install the dependencies we need to type:

```
npm i --save @nestjs/graphql apollo-server-express graphql
```

The above will give us the needed GraphQL binding for Nest `@nestjs/graphql` and the Apollo library for GraphQL server creation `apollo-server-express`.

Next up we need to configure something called `GraphQLModule` that we get from the library `@nestjs/graphql`. There are many ways to set this up but what we will tell it, at this point, is where to find the schema file. Therefore we will change `app.module.ts` to look like the following:

```ts
// app.module.ts

import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { AppResolver } from './app.resolver';
// import { join } from 'path';

@Module({
  imports: [
    GraphQLModule.forRoot({
      debug: false,
      playground: true,
      typePaths: ['./**/*.graphql']
    }),
  ],
  providers: [ AppResolver ]
})
export class AppModule { }
```

Let's have a closer look at the `GraphQLModule.forRoot()` invocation. Now, we see here that we set `playground` to true. This will give us a graphical way to pose our queries, more on that later. We also see that we set a property called `typePaths` and give it an array looking like so `['./**/*.graphql']`. Now, this is a pattern matching looking for all files ending with `.graphql`. The reason for this construct is that we can actually spread out our schema definition on several files. 

### Write our schema and resolvers

Next step is to create a file matching the above pattern so we create a file called `app.graphql` and we give it the following content:

```
// app.graphql

type Cat {
  id: Int
  name: String
  age: Int
}

type Query {
  getCats: [Cat]
  cat(id: ID!): Cat
}
```

Now this sets us up nicely, but what about resolver functions? Well, lets head back to `app.module.ts` and zoom in on a specific row `providers: [ AppResolver ]`. This is us wiring up `AppResolver` that will act as our resolver class. Let's have a closer look at `AppResolver`:

```ts
// app.resolver.ts

import { Args, Mutation, Query, Resolver, Subscription } from '@nestjs/graphql';
import { ParseIntPipe } from '@nestjs/common';


@Resolver('Cat')
export class AppResolver {
  cats = [{
    id: 1,
    name: 'Mjau',
    age: 17
  }]

  @Query()
  getCats() {
    console.log('getCats');
    return this.cats;
  }

  @Query('cat')
  async findOneById(
    @Args('id', ParseIntPipe)
    id: number,
  ): Promise<any> {
    return this.cats.find(c => c.id === id);
  }

}
```

As you can see we create a class `AppResolver` but it also comes with some interesting decorators. Let's explain those:

- `@Resolver`, this decorator tells GraphQL that this class should know how to resolve anything related to type `Cat`. 
- `Query()`, this says that the method being decorated by this will namewise match something defined in the `Query` in the schema. As we can see we have the method `getCats()` but in the case we don't plan to name match we need to send an arg into `Query` that says what part it matches. As you can see on the method `findOneById()` we decorate it with `Query('cat')` which simply means it resolves any queries to `cat`
- `@Args`, this decorator is used as a helper decorator to dig out any input parameters

### Take it for a spin
Let's first ensure we have all the necessary libraries by first typing:

```
npm install
```

This will install all needed dependencies. Once this finishes we should be ready to start. 

Next type so we can try out our API:

```
npm start
```
It should look something like this:

![](https://thepracticaldev.s3.amazonaws.com/i/hbf5b5bgz37kibiqsjr2.png)

Next step is to go to our browser at `http://localhost:3000/graphql`. You should see the following:

![](https://thepracticaldev.s3.amazonaws.com/i/xg71w5rojj7jernvslaf.png)

As you can see by above image we have defined two different queries called `oneCat` and `allCats` and you can see the query definition in each. In the one called `oneCat` you can see how we call `{ cat(id: 1){ name } }` which means we invoke the resolver for `cat` with the parameter `id` and value `1` and we select the field `name` on the result, which is of type `Cat`. The other query `allCats` are simple calling `{ getCats }` which matches with the same method on the `AppResolver` class

## Adding mutators
So far we have a fully working GraphQL API that works to query against but we are missing the mutator part, what if we want to support adding a cat, updating it or deleting it? To do that we need to do the following:

1. Add mutator operations to our schema
2. Add the needed resolver methods to our `AppResolver` class
3. Test it out

### Updating our schema

Ok, we need to add some mutators to the schema, ensure `app.graphql` now looks like the following:

```
type Cat {
  id: Int
  name: String
  age: Int
}

input CatInput {
  name: String
  age: Int,
  id: Int
}

type Mutation {
  createCat(cat: CatInput): String,
  updateCat(cat: CatInput): String,
  deleteCat(id: ID!): String
}

type Query {
  getCats: [Cat]
  cat(id: ID!): Cat
}
```

As you can see above we've added `Mutation` and `CatInput`

### Add resolvers

Ok, now we need to head back to `AppResolver` class and ensure it now looks like this:

```ts
// app.resolver.ts

import { Args, Mutation, Query, Resolver, Subscription } from '@nestjs/graphql';
import { ParseIntPipe } from '@nestjs/common';



@Resolver('Cat')
export class AppResolver {
  cats = [{
    id: 1,
    name: 'Cat1',
    age: 17
  }]

  @Mutation()
  createCat(
    @Args('cat')
    cat: any
  ): Promise<string> {
    this.cats = [...this.cats, {...cat, id: this.cats.length + 1}];
    return Promise.resolve('cat created');
  }

  @Mutation()
  updateCat(
    @Args('cat')
    cat: any
  ): Promise<string> {
    this.cats = this.cats.map(c => {
      if(c.id === cat.id) {
        return {...cat}
      }
      return c;
    });
    return Promise.resolve('cat updated');
  }

  @Mutation()
  deleteCat(
    @Args('id', ParseIntPipe)
    id: number
  ) : Promise<any> {
    this.cats = this.cats.filter(c => c.id !== id);
    return Promise.resolve('cat removed');
  }


  @Query()
  getCats() {
    console.log('getCats');
    return this.cats;
  }

  @Query('cat')
  async findOneById(
    @Args('id', ParseIntPipe)
    id: number,
  ): Promise<any> {
    return this.cats.find(c => c.id === id);
  }

}
```

The added parts are the methods `deleteCat()`, `updateCat()` and `createCat()`. 

## Additional features

We have a fully functioning API at this point. In fact, ensure your browser window looks like this and you will be able to test the full CRUD:

![](https://thepracticaldev.s3.amazonaws.com/i/94yokm9lu60dwlner6uw.png)

What do we mean by best practices? Well, we can do more than this to make our API easier to use like:

1. **Add types**, right now we have defined a lot of types in our `app.graphql` file but we could extract those types and use them in the resolver class
2. **Split up our API**, there is no need to have one gigantic schema file you can definitely split this up and let Nest stitch up all those files
3. **Define the API** by decorating DTOs, there is a second way of defining an API, what way is the best is up to you to judge

### Add types
I said we could extract the types from our schema to use them in the resolver class. That sounds great but I guess you are wondering how?

Well, you first need to head to `app.module.ts` and a property `definitions` and tell it two things. The first is what to name the file of generated types and secondly is what output type. The latter has two choices, `class` or `interface`. Your file should now look like this:

```
@Module({
  imports: [
    GraphQLModule.forRoot({
      debug: false,
      playground: true,
      typePaths: ['./**/*.graphql'],
      definitions: {
        path: join(process.cwd(), 'src/graphql.ts'),
        outputAs: 'class',
      }
    }),
  ],
  providers: [ AppResolver ]
})
export class AppModule { }
```

If you start up the API with `npm start` then `src/graphql.ts` will be created and it should look like this:

```ts
//graphql.ts


/** ------------------------------------------------------
 * THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
 * -------------------------------------------------------
 */

/* tslint:disable */
export class CatInput {
    name?: string;
    age?: number;
    id?: number;
}

export class Cat {
    id?: number;
    name?: string;
    age?: number;
}

export abstract class IMutation {
    abstract createCat(cat?: CatInput): string | Promise<string>;

    abstract updateCat(cat?: CatInput): string | Promise<string>;

    abstract deleteCat(id: string): string | Promise<string>;
}

export abstract class IQuery {
    abstract getCats(): Cat[] | Promise<Cat[]>;

    abstract cat(id: string): Cat | Promise<Cat>;
}

```

The takeaway for us is the types `Cat` and `CatInput` which we can use to make our `AppResolver` class a bit more type safe. Your `app.resolver.ts` file should now look like this:

```ts
// app.resolver.ts

import { Args, Mutation, Query, Resolver, Subscription } from '@nestjs/graphql';
import { ParseIntPipe } from '@nestjs/common';
import { Cat, CatInput } from './graphql';



@Resolver('Cat')
export class AppResolver {
  cats:Array<Cat> = [{
    id: 1,
    name: 'Cat1',
    age: 17
  }]

  @Mutation()
  createCat(
    @Args('cat')
    cat: CatInput
  ): Promise<string> {
    this.cats = [...this.cats, {...cat, id: this.cats.length + 1}];
    return Promise.resolve('cat created');
  }

  @Mutation()
  updateCat(
    @Args('cat')
    cat: CatInput
  ): Promise<string> {
    this.cats = this.cats.map(c => {
      if(c.id === cat.id) {
        return {...cat}
      }
      return c;
    });
    return Promise.resolve('cat updated');
  }

  @Mutation()
  deleteCat(
    @Args('id', ParseIntPipe)
    id: number
  ) : Promise<any> {
    this.cats = this.cats.filter(c => c.id !== id);
    return Promise.resolve('cat removed');
  }

  @Query()
  getCats(): Array<Cat> {
    return this.cats;
  }

  @Query('cat')
  async findOneById(
    @Args('id', ParseIntPipe)
    id: number,
  ): Promise<Cat> {
    return this.cats.find(c => c.id === id);
  }

}
```

Worth noting above is how our internal array `cats` is now of type `Cat` and the methods `createCat()` and `updateCat()` now has input of type `CatInput`. Furthermore the method `getCats()` return an array of `Cat` and lastly how the method `findOneById()` return a Promise of type `Cat`. 

### Split up our schema definitions

Now we said we could easily do this because of the way things are set up. This is easy to do just by creating another file called **.graphql. So when should I do that? Well, when you have different topics in your API it makes sense to do the split. Let's say you were adding dogs then it would make sense to have a separate `dogs.graphql` and also a separate resolver class for dogs. 

The point of this article was to show you how you could start and how you should gradually continue to add new types and new resolvers.  I hope you found it useful.

### 2nd way of defining things

The second way of defining a schema is outside the scope of this article, cause it would just be too long. However, have a look at how this is done is this [repo](https://github.com/nestjs/nest/tree/master/sample/23-type-graphql) and have a read [here](https://docs.nestjs.com/graphql/quick-start) under the headline "Code First"

## Summary

Now we have gone all the way from generating a new project, learned to define a schema and it's resolvers to generating types from our schema. We should be really proud of ourselves.