How to use TypeScript with GraphQL
Tags: tutorial, webdev, javascript, graphql
Published: 2021-01-25 22:01:27

---
title: How to use TypeScript with GraphQL
published: true
description: 
series: TypeScript + GraphQL + TypeGraphQL
tags: tutorial, webdev, javascript, graphql
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/s2t6cb5wgfsrdk1d4sw7.png
canonical_url: https://www.takeshape.io/articles/how-to-use-typescript-with-graphql/
---
GraphQL is a powerful query language that allows you to build flexible APIs. It lets you define a type system for your data, so when you execute a query, it returns only the data you need.

GraphQL can offer a better developer experience when used with TypeScript because they are both typed language. TypeScript is a typed superset of JavaScript that extends it by adding types. So, using these technologies together will certainly help you to build predictable and strongly-types APIs.

In this tutorial, I will first explain why combining such technologies, and then show you how to use TypeScript with GraphQL by building an API from scratch using TypeGraphQL.

## Prerequisites

This tutorial assumes that you have some experience using TypeScript, particularly TypeScript classes and decorators. Knowledge of GraphQL will come in handy but is not mandatory.

In this guide, we will be using [TypeGraphQL](https://typegraphql.com/), which is a modern framework for building GraphQL API using Node.js and TypeScript.

## Why use TypeScript with GraphQL

TypeScript is a popular programming language developed and maintained by Microsoft. It is a superset of JavaScript that uses static type-checking to make your code predictable.

Over the years, TypeScript has proven to be a valuable language for large codebases. TypeScript enhances code quality with its types, which adds many benefits, such as robustness, understandability, and predictability.

GraphQL solves the problem of over-fetching or under-fetching APIs. It provides one single endpoint for all requests using a _`Post`_ method to get exactly the data you need, nothing more and nothing less. In this way, GraphQL makes your queries flexible, and your API readable and easy to learn.

TypeScript and GraphQL both rely on types to make your code understandable. However, GraphQL types can only be defined in a GraphQL schema using the method `buildSchema` or a file with `.gql` extension. The GraphQL types are not supported on GraphQL resolvers because resolvers are just regular JavaScript functions, not GraphQL code. TypeScript solves this issue because, as we mentioned earlier, it’s a superset of JavaScript. So, It can set types on the GraphQL resolvers. This is the reason why using TypeScript along with GraphQL makes sense.

GraphQL handles the types for the GraphQL schemas, and TypeScript sets the types on the GraphQL resolvers. However, because you are handling multiple languages, building strongly-typed APIs using Node.js, GraphQL, and TypeScript can be a challenge to maintain.

Maintaining consistency between your schema and resolvers is what TypeGraphQL intends to solve. TypeGraphQL allows you to use TypeScript classes and decorators to create the schema, types, and resolvers of your API. It uses TypeScript to build the entire GraphQL API.

![https://paper-attachments.dropbox.com/s_FE1E1F2FD073B6FBA4EBF25A186A644F8A1660C235BABE83F3933C922FDEEEEB_1600278411563_illustration.png](https://paper-attachments.dropbox.com/s_FE1E1F2FD073B6FBA4EBF25A186A644F8A1660C235BABE83F3933C922FDEEEEB_1600278411563_illustration.png)

illustration

So far, we have learned why pairing TypeScript with GraphQL can be useful and why TypeGraphQL is handy for building and maintaining GraphQL APIs that use TypeScript.

Without further ado, let’s dive into the practice part and build up the GraphQL API using TypeGraphQL.

## Setting up

To use TypeScript and GraphQL, we first need to create a new Node.js app.

Open your command-line interface (CLI) and run this command:

```bash
yarn init
```

Or for `npm`

```bash
npm init
```

You’ll need to respond to a few configuration questions which will emit a `package.json` file. Next, install the dependencies needed for this tutorial.

```bash
yarn add express apollo-server-express graphql reflect-metadata type-graphql class-validator
```

For `npm`

```bash
npm install express apollo-server-express graphql reflect-metadata type-graphql class-validator
```

We will break these packages down later and explain what they do. For now, let’s install their types so TypeScript can understand the libraries.

```bash
yarn add -D @types/express @types/node nodemon
```

Or

```bash
npm install -D @types/express @types/node nodemon
```

Note that we installed `nodemon` as well to enable live-reloading whenever a change occurs.

Here’s what each of the installed libraries do:

- `express` is a minimalist web framework for Node.js
- `apollo-server-express` is a middleware that allows using `express` in an Apollo GraphQL server.
- `reflect-metadata` enables TypeScript decorators to add the ability to augment a class and its members when the class is defined. It’s a dependency of TypeGraphQL.
- `class-validator` allows TypeGraphQL to use decorator and non-decorator based validation.

Next, we need to structure the project as follows:

```bash
src
| ├── resolvers
| |  └── todoResolver.ts
| └── schemas
| |  └── Todo.ts
| └── index.ts
├── tsconfig.json
├── package.json
└── yarn.lock
```

Here, there are four files to underline:

- The entry point of the server (`index.ts`).
- The `schemas` folder that contains the GraphQL Schema of the project.
- The `resolvers` folder that holds the resolvers of the API.
- The `tsconfig.json` file tells to TypeScript how to compile the code.

With this in place, we can now add a script to start the server in the `package.json` file.

```json
"scripts": {
  "start": "nodemon --exec ts-node src/index.ts"
}
```

This script will start the server using `nodemon`. And whenever our code is updated, it will restart.

Let’s now configure the `tsconfig.json`.

```json
{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  }
}
```

These two properties should be set to `true` to be able to use TypeScript decorators in the project.

We can now build a GraphQL Schema for the API.

## Build the GraphQL Schema

TypeGraphQL allows you to build a schema using TypeScript classes and decorators. It’s just syntactic sugar because under the hood TypeGraphQL will still generate regular GraphQL code. We will see the code generated later - for now, let’s create the schema.

- `schemas/Todo.ts`

```typescript
import { Field, ObjectType, InputType } from ‘type-graphql’

@ObjectType() export class Todo {
  @Field() id: number
  @Field() title: string
  @Field() description: string
  @Field() status: boolean
}

@InputType() export class TodoInput implements Partial {
  @Field() title: string
  @Field() description: string
}
```

At the first the syntax might look weird, however, it’s relatively simple to understand. It’s just TypeScript decorators and classes.

Here, the `@ObjectType()` provided by TypeGraphQL enables creating a new object or schema. The `Todo` class reflects the shape of a Todo object, and the `TodoInput` defines the expected data for adding a new Todo.

Now, let’s write the same code using GraphQL.

```typescript
type Todo {
  id: ID!
  title: String!
  description: String!
  status: Boolean!
}

input TodoInput {
  title: String!
  description: String!
}
```

As you can see, the logic is the same. The only difference is that here, we don’t use TypeScript.

Now we’re ready to create our GraphQL resolvers.

## Create the GraphQL resolver

Unlike GraphQL, TypeGraphQL puts the GraphQL query or mutation in the resolvers. The name of the function will be used as an endpoint when querying or mutating data.

- `resolvers/todoResolver.ts`

```typescript
import { Query, Resolver, Mutation, Arg } from ‘type-graphql’;
import { Todo, TodoInput } from ‘../schemas/Todo’;

@Resolver((of) => Todo) export class TodoResolver { 
    private todos: Todo[] = []

    @Query((returns) => [Todo], { nullable: true })
    async getTodos(): Promise<Todo[]> {
        return await this.todos
    }

    @Mutation((returns) => Todo)
    async addTodo(
        @Arg('todoInput') { title, description }: TodoInput
    ): Promise<Todo> {
        const todo = {
            id: Math.random(), // not really unique
            title,
            description,
            status: false,
        }

        await this.todos.push(todo)
        return todo
    }
}
```

Here, we use the `Resolver` decorator to create a new GraphQL resolver that returns a Todo. Next, we build a GraphQL query to fetch all Todos.

After that, we define a mutation query that expects a `title`, and a `description` to add a new Todo on the array of data.

By the way, you don’t need to use async/await here, because this won’t take time to complete. But, I add it here for reference when you need to deal with a real server.

Let’s now convert the code to GraphQL.

```typescript
type Mutation {
  addTodo(todoInput: TodoInput!): Todo!
}

type Query {
  getTodos: [Todo!]
}
```

With this in place, we can build the server that uses the schema and resolver we’ve just created.

## Create the Server

- `src/index.ts`

```typescript
import ‘reflect-metadata’;
import { ApolloServer } from ‘apollo-server-express’;
import * as Express from ‘express’ import { buildSchema } from ‘type-graphql’;
import { TodoResolver } from ‘./resolvers/todoResolver’;

async function main() { const schema = await buildSchema({ resolvers: [TodoResolver], emitSchemaFile: true, })

    const app = Express()

    const server = new ApolloServer({
        schema,
    })

    server.applyMiddleware({ app })

    app.listen(4000, () =>
        console.log('Server is running on http://localhost:4000/graphql')
    )

}

main()
```

As you can see here, we import `TodoResolver`, which needs to be passed as a resolver to the `buildSchema` method. With that, TypeGraphQL can build a new GraphQL Schema based on the Todo resolver.

Next, we pass the `schema` object (it contains the GraphQL schemas and resolvers) to Apollo to create the server.

Setting the property `emitSchemaFile: true` allows TypeGraphQL to generate a `schema.gql` file at build-time.

Let’s check if the app works. Run the following command:

```bash
yarn start
```

Or

```bash
npm start
```

Visit `http://localhost:4000/graphql`, and then add this code block below to GraphQL Playground to create a new Todo.

```typescript
mutation {
  addTodo(todoInput: { title: "Todo 1", description: "This is my todo" }) {
    title
    description
    status
  }
}
```

The Todo object should be created successfully!

![https://paper-attachments.dropbox.com/s_FE1E1F2FD073B6FBA4EBF25A186A644F8A1660C235BABE83F3933C922FDEEEEB_1599926790317_add-todo.PNG](https://paper-attachments.dropbox.com/s_FE1E1F2FD073B6FBA4EBF25A186A644F8A1660C235BABE83F3933C922FDEEEEB_1599926790317_add-todo.PNG)

todo-created

Now query for the newly created Todo using the following GraphQL query.

```graphql
{
  getTodos {
    title
    description
    status
  }
}
```

You should see that all Todos have been returned.

![https://paper-attachments.dropbox.com/s_FE1E1F2FD073B6FBA4EBF25A186A644F8A1660C235BABE83F3933C922FDEEEEB_1599926830468_all-todos.PNG](https://paper-attachments.dropbox.com/s_FE1E1F2FD073B6FBA4EBF25A186A644F8A1660C235BABE83F3933C922FDEEEEB_1599926830468_all-todos.PNG)

all-todos

Great! Our app looks good.

We have now finished building a GraphQL API using TypeScript.

You can find the finished project in this [Github repo](https://github.com/ibrahima92/typescript-graphql-api)

Thanks for reading

## GraphQL in TakeShape

TakeShape provides a flexible GraphQL API to manage your content easily. It gives you the ability to immediately see how changes to your content model will impact your API using the API Explorer. You don’t have to build any backend on your own, everything is set up for you. TakeShape automatically generates a secure GraphQL API to expose all of your content and services.

## Next steps

Check out these resources to dive deeper into the content of this tutorial:

- [TypeGraphQL Docs](https://typegraphql.com/docs/introduction.html)
- [TypeScript Decorators Docs](https://www.typescriptlang.org/docs/handbook/decorators.html)
- [TypeScript Classes Docs](https://www.typescriptlang.org/docs/handbook/classes.html)
- [TypeGraphQL Examples](https://typegraphql.com/docs/examples.html)
- [GraphQL Docs](https://graphql.org/learn/)