Integrating TypeScript with GraphQL
Tags: graphql, typescript, tutorial
Published: 2020-04-22 13:22:28

---
title: Integrating TypeScript with GraphQL
published: true
date: 2020-03-25 16:00:29 UTC
tags: graphql,typescript,tutorial
canonical_url: https://blog.logrocket.com/integrating-typescript-graphql/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/ywp0zkoci2cohvqkxvgi.jpeg
---
**Written by [Alexander Nnakwue](https://blog.logrocket.com/author/alexandernnakwue/)**✏️

## Introduction

TypeScript, a typed superset of JavaScript, comes with design features that aim to solve the many pain points of writing applications in JavaScript. With its numerous feature sets and [functionalities](https://www.typescriptlang.org/docs/home.html#toc-handbook), including interfaces, generics, optional type-checking, and type inference, it shines majorly when it comes to developer productivity.

With the latest features from ES6, including decorators, async/await, etc., it’s backwards-compatible, with a few edge cases. It compiles down to plain JavaScript and is therefore a great target for older environments.

On the other hand, GraphQL, as we know, is a query language for APIs. Using its type system to describe data fields, it aids in fetching the exact data we queried for without over-fetching or under-fetching. Also, it can greatly help in the area of [API versioning](https://graphql.org/learn/best-practices/#versioning). To learn more about the benefits of GraphQL, please take a peek at its awesome [documentation](https://graphql.org/).

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## Prerequisites

In order to follow along with this tutorial, it would be best to have a basic or foundational knowledge of TypeScript and GraphQL. To run our code, it is advisable to have Node.js installed on your machine. Instructions to do so are available in the [documentation](https://nodejs.org/en/).

Also, you should have TypeScript installed globally on your machine. To do so, you can run the following command on your terminal or command prompt using `npm` or `yarn`. Below, we are using `npm`:

```jsx
npm install -g typescript
```

> **Note** : This command installs the latest TypeScript compiler on our system path, useful when compiling and running our code. The compiler known as `tsc` takes a TypeScript file ending with the `.ts` extension and outputs an equivalent JavaScript file, with the `.js` extension. Not to worry — as we proceed, we will be learning more about this command.

## Introducing TypeGraphQL and bootstrapping our application

In this tutorial, we are going to learn how to integrate TypeScript with GraphQL using the TypeGraphQL library by building an API.

[TypeGraphQL](https://typegraphql.ml/docs/introduction.html) makes developing GraphQL APIs in Node an awesome experience by automatically creating GraphQL schema definitions from TypeScript classes with [decorators](https://www.typescriptlang.org/docs/handbook/decorators.html#introduction). Decorators (and reflection) were introduced to avoid the need for schema definition files and interfaces describing these schemas.

More details about the library’s motivation can be found in [this section](https://typegraphql.com/docs/introduction.html) of the documentation. Note that we can write [custom decorators](https://typegraphql.com/docs/custom-decorators.html) to suit our specific needs based on a project’s requirements. However, for this tutorial, the provided decorators for TypeGraphQL would suffice.

Without further ado, let us get to the meat of our learning. First of all, we can go ahead and create a new directory and give it any name we want. We can then initialize a new `package.json` file with the `npm init` command. After we are done installing all of our project’s dependencies, our `package.json` file should look like this:

```jsx
{
  "name": "typscript-graphql-logrocket-tutorial",
  "version": "1.0.0",
  "description": "A typscript and graphql Tutorial",
  "main": "server.js",
  "scripts": {
    "start": "npm run serve",
    "serve": "node dist/server.js",
    "watch-node": "nodemon dist/server.js",
    "build-ts": "tsc",
    "watch-ts": "tsc -w",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "Tyscript",
    "Graphql",
    "node",
    "javascript"
  ],
  "author": "Alexander Nnakwue",
  "license": "MIT",
  "devDependencies": {
    "@types/express": "^4.17.3",
    "@types/graphql": "^14.5.0",
    "@types/node": "^13.9.0",
    "nodemon": "^2.0.2",
    "ts-node": "^8.6.2",
    "typescript": "^3.8.3"
  },
  "dependencies": {
    "@typegoose/typegoose": "^6.4.0",
    "apollo-server-express": "^2.11.0",
    "class-validator": "^0.11.0",
    "express": "^4.17.1",
    "graphql": "^14.6.0",
    "reflect-metadata": "^0.1.13",
    "type-graphql": "^0.17.6"
  }
}
```

## Bootstrapping our application

### Installation and setup

Before we proceed, we need to install all the required dependencies for our project. We can go ahead and run the following command in our terminal:

```jsx
npm install type-graphql reflect-metadata graphql express class-validator apollo-server-express mongoose @typegoose/typegoose --save
```

Like we mentioned earlier, `type-graphql` is the framework we will be using for building our API with TypeScript and GraphQL. It comes with a lot of advanced features, like [automatic validation](https://typegraphql.com/docs/validation.html), [dependency injection](https://typegraphql.com/docs/dependency-injection.html), [authorization](https://typegraphql.com/docs/authorization.html), [inheritance](https://typegraphql.com/docs/inheritance.html), and so on. The library also allows us to define our GraphQL schema types and interfaces using TypeScript classes and decorators.

### Discussion

From the dependencies installed above, `reflect-metadata` adds a polyfill for the [experimental Metadata API](https://github.com/rbuckton/ReflectDecorators) support for TypeScript.

Currently, TypeScript includes experimental support for emitting certain types of metadata for declarations that have decorators. This means we must enable support for this library in our `tsConfig.json` file, as we will see later. More details about the reflect-metadata package can be found [here](https://www.typescriptlang.org/docs/handbook/decorators.html#metadata).

The `apollo-server-express` library is the Express and Connect integration of a GraphQL server. Here, we will be using this library to bootstrap a simple GraphQL server with Express. It depends on `express` to work. More details can be found [here](https://www.apollographql.com/docs/apollo-server/v1/servers/express/).

The [`class-validator`](https://github.com/typestack/class-validator) library allows the use of decorator- and non-decorator-based [validation](https://typegraphql.com/docs/validation.html) with TypeGraphQL. We will be using it here to validate our schema fields.

The `mongoose` package, as we know, is the MongoDB object data mapper (ODM), while the `@types/mongoose` package provide TypScript definitions for it. Lastly, `@typegoose/typegoose` allows us to define Mongoose models using TypeScript classes. More details can be found [here](https://github.com/szokodiakos/typegoose#motivation).

We should also go ahead and install these TypeScript definitions types as dev dependencies: `types/express`, `@types/graphql`, and `@types/node`. Additionally, we should add `typescript`, `ts-node` (TypeScript execution environment for Node.js), and `nodemon` as dev dependencies. Run the following:

```jsx
npm install types/express @types/graphql @types/node typescript ts-node @types/mongoose nodemon --save-dev
```

After we complete the above, we then need to set up our `tsConfig.json` file, which provides instructions on how our TypeScript project should be configured. For TypeGraphQL, the required TS configuration is shown [here](https://typegraphql.com/docs/installation.html#typescript-configuration).

In this file, we can specify compiler options to compile our `.ts` files as well as the root files for our project. So, whenever we run the `tsc` command (`npm run build`, in our case, based on our `package.json` file setup), the compiler will check this file first for special instructions and then proceed with compilation based on those instructions.

To create one, we can run the `tsc --init` command. This command creates a new config file with a lot of defaults and comments, which has been stripped here for brevity. Here is how our `tsConfig` file looks:

```jsx
  {
    "compilerOptions": {
        "module": "commonjs",
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "target": "es2016",  // or newer if your node.js version supports this
        "strictNullChecks": true,
        "strictFunctionTypes": true,
        "noImplicitThis": true,
        "noUnusedLocals": true,
        "noUnusedParameters": true,
        "noImplicitReturns": true,
        "skipLibCheck": true,
        "declaration": false,
        "noFallthroughCasesInSwitch": true,
        "composite": false,
        "noImplicitAny": true,
        "moduleResolution": "node",
        "lib": ["dom", "es2016", "esnext.asynciterable"],
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "strict": false,
        "experimentalDecorators": true,
        "outDir": "dist",
        "rootDir": "app",
        "baseUrl": ".",
        "paths": {
            "*": [
                "node_modules/*",
                "app/types/*"
            ]
        }
    },
    "include": [
        "app/**/*", "./app/**/*.ts", "./app/**/*.tsx"
    ]
}
```

> **Note** : Detailed interpretations and meanings of these configuration options can be found in [the documentation here](https://github.com/MichalLytek/type-graphql/blob/master/tsconfig.json).

## Setting up our GraphQL server

Now we can go ahead and set up an Apollo server with the `apollo-server-express` package we installed earlier. But before we do so, we’ll create a new app directory in our project directory. The contents of the directory should look like this:

![The Contents Of Our App Folder](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/app-folder-contents.png?resize=412%2C216&ssl=1)<figcaption id="caption-attachment-16013">The contents of our app folder.</figcaption>

In our `server.js` file, we are going to set up our Apollo server with Express. The contents of the file, with all the imports, should look like this:

```jsx
import { ApolloServer } from "apollo-server-express";
import Express from "express";
import "reflect-metadata";
import { buildSchema } from "type-graphql";
import { connect } from "mongoose";

// resolvers
import {UserResolver} from "./resolvers/User";
import {ProductResolver} from "./resolvers/Product";
import {CategoriesResolver} from "./resolvers/Categories";
import {CartResolver} from "./resolvers/Cart";
import {OrderResolver} from "./resolvers/Order";


const main = async () => {
const schema = await buildSchema({
    resolvers: [CategoriesResolver, ProductResolver, UserResolver, CartResolver, OrderResolver ],
    emitSchemaFile: true,
    validate: false,
  });

// create mongoose connection
const mongoose = await connect('mongodb://localhost:27017/test', {useNewUrlParser: true});
await mongoose.connection;


const server = new ApolloServer({schema});
const app = Express();
server.applyMiddleware({app});
app.listen({ port: 3333 }, () =>
  console.log(`🚀 Server ready and listening at ==> http://localhost:3333${server.graphqlPath}`))
};
main().catch((error)=>{
    console.log(error, 'error');
})
```

### Discussion

Here we are importing the dependencies needed to set up our server.

Earlier, we talked about the `apollo-server-express` package, `mongoose` for our database connection, and the `reflect-metadata` package. The `buildSchema` package from TypeGraphQL allows us to use this method to build our schema from TypeGraphQL’s definition. This is the usual signature of the `buildSchema` method:

```jsx
const schema = await buildSchema({
  resolvers: [Resolver],
});
```

As we can see above, we are importing our resolvers from the `app/resolver` folder and passing them into the array of the `resolvers field` inside the function definition. The `emitSchemaFile` field allows us to spit out our GraphQL schema into a `schema.gql` file when we run the `npm run build-tsc` command. The content of the file looks like this:

```jsx
# -----------------------------------------------
# !!! THIS FILE WAS GENERATED BY TYPE-GRAPHQL !!!
# !!!   DO NOT MODIFY THIS FILE BY YOURSELF   !!!
# -----------------------------------------------

"""The  Cart model"""
type Cart {
  id: ID!
  products: String!
  product: Product!
}

input CartInput {
  products: ID!
}

"""The Categories model"""
type Categories {
  id: ID!
  name: String!
  description: String!
}

input CategoriesInput {
  name: String!
  description: String!
}

"""
The javascript `Date` as string. Type represents date and time as the ISO Date string.
"""
scalar DateTime

type Mutation {
  createUser(data: UserInput!): User!
  deleteUser(id: String!): Boolean!
  createProduct(data: ProductInput!): Product!
  deleteProduct(id: String!): Boolean!
  createCategory(data: CategoriesInput!): Categories!
  deleteCategory(id: String!): Boolean!
  createCart(data: CartInput!): Cart!
  deleteCart(id: String!): Boolean!
  createOrder(data: OrderInput!): Order!
  deleteOrder(id: String!): Boolean!
}

"""The Order model"""
type Order {
  id: ID!
  user_id: String!
  payde: Boolean!
  date: DateTime!
  products: Product!
}

input OrderInput {
  user_id: String!
  payde: Boolean!
  date: DateTime!
}

"""The Product model"""
type Product {
  id: ID!
  name: String!
  description: String!
  color: String!
  stock: Int!
  price: Int!
  category_id: String!
  category: Categories!
}

input ProductInput {
  name: String!
  description: String!
  color: String!
  stock: Float!
  price: Float!
  category_id: String!
}

type Query {
  returnSingleUser(id: String!): User!
  returnAllUsers: [User!]!
  returnSingleProduct(id: String!): Order!
  returnAllProduct: [Product!]!
  returnSingleCategory(id: String!): Categories!
  returnAllCategories: [Categories!]!
  returnSingleCart(id: String!): Cart!
  returnAllCart: [Cart!]!
  returnAllOrder: [Order!]!
}

"""The User model"""
type User {
  id: ID!
  username: String!
  email: String!
  cart_id: String!
  cart: Cart!
}

input UserInput {
  username: String!
  email: String!
  cart_id: ID!
}
```

> **Note** : The content of this file is based on what we have in the schema fields for our different database entities, which are contained in the `entities` folder. In the next section, we are going to be looking at the contents of these files.

## Creating our database schema fields/entities with TypeGraphQL

As we can see in the app folder above, we have a folder called `entities`. Inside that folder, we have files that represents all the database entities we need. The contents of these files are shown below:

#### `Categories.ts`

```jsx
import { ObjectType, Field, ID } from "type-graphql";
import { prop as Property, getModelForClass } from "@typegoose/typegoose";

@ObjectType({ description: "The Categories model" })
export class Categories {
    @Field(()=> ID)
    id: string;

    @Field() 
    @Property()
    name: String;

    @Field()
    @Property()
    description: String;
}

export const CategoriesModel = getModelForClass(Categories);
```

#### `Product.ts`

```jsx
import { ObjectType, Field, ID, Int } from "type-graphql";
import { prop as Property, getModelForClass } from "@typegoose/typegoose";
import { Ref } from "../types";
import {Categories} from "./Categories";
import { __Type } from "graphql";

@ObjectType({ description: "The Product model" })
export  class Product {
    @Field(() => ID)
    id: String; 

    @Field()
    @Property()
    name: String;

    @Field()
    @Property()
    description: String;

    @Field()
    @Property()
    color: String;

    @Field(_type => Int)
    @Property()
    stock: number;

    @Field(_type => Int)
    @Property()
    price: number;

    @Field(_type => String)
    @Property({ref: Categories})
    category_id: Ref<Categories>;
    _doc: any;
}

export const ProductModel = getModelForClass(Product);
```

#### `Cart.ts`

```jsx
import { ObjectType, Field, ID} from "type-graphql";
import { prop as Property, getModelForClass } from "@typegoose/typegoose";

import { Ref } from "../types";
import {Product} from "./Product";

@ObjectType({ description: "The  Cart model" })
export  class Cart {
    @Field(() => ID)
    id: string;  

    @Field(_type => String)
    @Property({ ref: Product, required: true })
    products: Ref<Product>;
    _doc: any;
}

export const CartModel = getModelForClass(Cart);
```

#### `Users.ts`

```jsx
import { ObjectType, Field, ID } from "type-graphql";
import { prop as Property, getModelForClass } from "@typegoose/typegoose";
import { Ref } from "../types";
import {Cart} from "./Cart";

@ObjectType({ description: "The User model" })
export class User {

    @Field(() => ID)
    id: number;  

    @Field()
    @Property({ required: true })
    username: String;

    @Field()
    @Property({ required: true })
    email: String;

    @Field(_type => String)
    @Property({ ref: Cart, required: true})
    cart_id: Ref<Cart>
}

export const UserModel = getModelForClass(User);
```

#### `Order.ts`

```jsx
import { ObjectType, Field, ID } from "type-graphql";
import { prop as Property, getModelForClass} from "@typegoose/typegoose";

import { Ref } from "../types";
import {Product} from "./Product";

@ObjectType({ description: "The Order model" })
export  class Order {
    @Field(()=> ID)
    id: String; 

    @Field()
    @Property({ nullable: true })
    user_id: String;

    @Field()
    @Property({ required: true })
    payde: Boolean;

    @Field()
    @Property({ default: new Date(), required: true, nullable: true })
    date: Date;

    // @Field(_type => Product)
    @Property({ ref: Product, required: true })
    products: Ref<Product>
    _doc: any;
}

export const OrderModel = getModelForClass(Order);
```

### Discussion

As we can see in the files above, we are importing the `ObjectType`, `Field`, `ID`, and `Int` from `type-graphql`. The `@Field` decorator is used to declare which class properties should be mapped to the GraphQL fields. It is also used to collect metadata from the TypeScript reflection system.

The `@ObjectType` decorator marks the class as the `type` known as [GraphQLObjectType](https://graphql.org/graphql-js/type/#graphqlobjecttype) from `graphql-js`. `Int` and `ID` are aliases for three basic GraphQL scalars. More details can be found [here](https://typegraphql.com/docs/scalars.html).

Also, from the `@typegoose/typegoose` package, we are importing both the `Property` decorator and the `getModelForClass` method. The `Property` decorator is used for setting properties in a class, without which is just a type and will not be in the final model. Details can be found [here](https://typegoose.github.io/typegoose/docs/decorators/prop/).

The `getModelForClass` method is used to get a model for a given class. More details can be found [here](https://typegoose.github.io/typegoose/docs/functions/getModelForClass/).

Lastly, we are importing `Refs` from the `types.ts` file in the app folder. The content of the file is shown below:

```jsx
import { ObjectId } from "mongodb";
export type Ref<T> = T | ObjectId;
```

Here we are importing `[ObjectId](https://docs.mongodb.com/manual/reference/method/ObjectId/)` from MongoDB.

> **Note** : The type `Ref<T>` is the type used for References. It also comes with typeguards for validating these references. More details can be found [here](https://typegoose.github.io/typegoose/docs/types/ref/).

## Resolvers and input types for our entities

Here, we can go ahead and create a new folder called `resolver`. This folder contains another folder called `types`, which contains the types for our different resolver inputs. The input files are shown below:

#### `categories-input.ts`

```jsx
import { InputType, Field } from "type-graphql";
import { Length } from "class-validator";
import { Categories } from "../../entities/Categories";

@InputType()
export class CategoriesInput implements Partial<Categories> {

  @Field()
  name: string;

  @Field()
  @Length(1, 255)
  description: String;

}
```

#### `categories-input.ts`

```jsx
import { InputType, Field } from "type-graphql";
import { Length } from "class-validator";
import { Product } from "../../entities/Product";
import { ObjectId } from "mongodb";

@InputType()
export class ProductInput implements Partial<Product> {
  @Field()
  name: String;

  @Field()
  @Length(1, 255)
  description: String;

  @Field()
  color: String;

  @Field()
  stock: number;

  @Field()
  price: number;

  @Field(()=> String)
  category_id: ObjectId;
}
```

#### `cart-input.ts`

```jsx
import { InputType, Field, ID } from "type-graphql";
import { Cart } from "../../entities/Cart";
import { ObjectId } from "mongodb";

@InputType()
export class CartInput implements Partial<Cart> {

    @Field(()=> ID)
    products?: ObjectId;

}
```

#### `user-input.ts`

```jsx
import { InputType, Field, ID } from "type-graphql";
import { Length, IsEmail } from "class-validator";
import { User } from "../../entities/User";
import { ObjectId } from "mongodb";

@InputType()
export class UserInput implements Partial<User> {
  @Field()
  @Length(1, 255)
  username: String;

  @Field()
  @IsEmail()
  email: String;

  @Field(()=> ID)
  cart_id: ObjectId;  
}
```

#### `order-input.ts`

```jsx
import { InputType, Field } from "type-graphql";
import { Order } from "../../entities/Order";

@InputType()
export class OrderInput implements Partial<Order> {
  @Field()
  user_id: String;

  @Field()
  payde: Boolean;

  @Field()
  date: Date;

}
```

### Discussion

As we can see in the input files above, we are importing the `InputType` and `Field` decorators from `type-graphql`. The `inputType` decorator is used by TypeGraphQL to automatically validate our inputs and arguments based on their definitions.

We can also see we are using the `class-validator` library for field-level validation. Note that TypeGraphQL has built-in support for argument and input validation based off this library.

Moving on, let’s examine the resolvers for these inputs and entities. For the category resolver in the `categories.ts` file, the content is shown below:

```jsx
import { Resolver, Mutation, Arg, Query } from "type-graphql";
import { Categories, CategoriesModel } from "../entities/Categories";
import { CategoriesInput } from "./types/category-input"

@Resolver()
export class CategoriesResolver {

    @Query(_returns => Categories, { nullable: false})
    async returnSingleCategory(@Arg("id") id: string){
      return await CategoriesModel.findById({_id:id});
    };


    @Query(() => [Categories])
    async returnAllCategories(){
      return await CategoriesModel.find();
    };

    @Mutation(() => Categories)
    async createCategory(@Arg("data"){name,description}: CategoriesInput): Promise<Categories> { 
      const category = (await CategoriesModel.create({      
          name,
          description
      })).save();
      return category;
    };


   @Mutation(() => Boolean)
   async deleteCategory(@Arg("id") id: string) {
    await CategoriesModel.deleteOne({id});
    return true;
  }

}
```

This resolver performs basic CRUD operations using the `Resolver`, `Mutation`, `Arg`, and `Query` decorators from `type-graphql`. We can also see that we are importing the input types to be used for the mutation field.

For the product resolver file, we have:

```jsx
import { Resolver, Mutation, Arg, Query,  FieldResolver, Root } from "type-graphql";
import { Product, ProductModel } from "../entities/Product";
import { ProductInput } from "./types/product-input"
import {  Categories, CategoriesModel } from "../entities/Categories";


@Resolver(_of => Product)
export class ProductResolver {

    @Query(_returns => Product, { nullable: false})
    async returnSingleProduct(@Arg("id") id: string){
      return await ProductModel.findById({_id:id});
    };

    @Query(() => [Product])
    async returnAllProduct(){
      return await ProductModel.find();
    };

    @Mutation(() => Product)
    async createProduct(@Arg("data"){name,description, color, stock, price, category_id}: ProductInput): Promise<Product> { 
      const product = (await ProductModel.create({      
          name,
          description,
          color,
          stock,
          price,
         category_id   
      })).save();
      return product;
    };

   @Mutation(() => Boolean)
   async deleteProduct(@Arg("id") id: string) {
    await ProductModel.deleteOne({id});
    return true;
  }

  @FieldResolver(_type => (Categories))
  async category(@Root() product: Product): Promise<Categories> {
    console.log(product, "product!")
    return (await CategoriesModel.findById(product._doc.category_id))!;
  }
}
```

> **Note** : The product resolver above contains a field resolver decorator for relational entity data. In our case, the product schema has a `category-id` field for fetching details about a particular category, which we have to resolve by fetching that data from another node in our data graph.

To learn more about resolvers and how they work, check out the [documentation for resolvers](https://github.com/MichalLytek/type-graphql/blob/master/docs/resolvers.md). More details about our other resolver files can be found in the GitHub repo [here](https://github.com/firebase007/typescript-graphql).

## Running our application

To start our application, we first run `npm run build-tsc`, which compiles our code, then `npm start`, which starts up our server. Note that TypeScript catches any compile-time errors when we build our code with the compiler (`.tsc`).

![Output After Running Our Commands](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/console-output.png?resize=730%2C144&ssl=1)<figcaption id="caption-attachment-16014">Output after running npm run build-tsc and npm start</figcaption>

After we are done, we can navigate to the GraphQL playground at [`http://localhost:3333/graphql`(http://localhost:3333/graphql) to test our API 🙂.

Let’s create a new category:

![Creating A New Category](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/creating-new-category.png?resize=730%2C398&ssl=1)<figcaption id="caption-attachment-16016">Creating a new category.</figcaption>

Let’s get a category by ID:

![Returning A Single Category By Its ID](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2020/03/returning-single-category.png?resize=730%2C397&ssl=1)<figcaption id="caption-attachment-16018">Returning a single category by ID.</figcaption>

Awesome, right? More details on the capabilities of the API can be found when we click on the schema tab in the playground. The details are shown below:

```jsx
type Cart {
  id: ID!
  products: String!
  product: Product!
}

input CartInput {
  products: ID!
}

type Categories {
  id: ID!
  name: String!
  description: String!
}

input CategoriesInput {
  name: String!
  description: String!
}

scalar DateTime

type Mutation {
  createUser(data: UserInput!): User!
  deleteUser(id: String!): Boolean!
  createProduct(data: ProductInput!): Product!
  deleteProduct(id: String!): Boolean!
  createCategory(data: CategoriesInput!): Categories!
  deleteCategory(id: String!): Boolean!
  createCart(data: CartInput!): Cart!
  deleteCart(id: String!): Boolean!
  createOrder(data: OrderInput!): Order!
  deleteOrder(id: String!): Boolean!
}

type Order {
  id: ID!
  user_id: String!
  payde: Boolean!
  date: DateTime!
  products: Product!
}

input OrderInput {
  user_id: String!
  payde: Boolean!
  date: DateTime!
}

type Product {
  id: ID!
  name: String!
  description: String!
  color: String!
  stock: Int!
  price: Int!
  category_id: String!
  category: Categories!
}

input ProductInput {
  name: String!
  description: String!
  color: String!
  stock: Float!
  price: Float!
  category_id: String!
}

type Query {
  returnSingleUser(id: String!): User!
  returnAllUsers: [User!]!
  returnSingleProduct(id: String!): Order!
  returnAllProduct: [Product!]!
  returnSingleCategory(id: String!): Categories!
  returnAllCategories: [Categories!]!
  returnSingleCart(id: String!): Cart!
  returnAllCart: [Cart!]!
  returnAllOrder: [Order!]!
}

type User {
  id: ID!
  username: String!
  email: String!
  cart_id: String!
  cart: Cart!
}

input UserInput {
  username: String!
  email: String!
  cart_id: ID!
}
```

To learn more, we can test the queries and the mutations in the schema tab shown above.

## Conclusion

The main idea of TypeGraphQL is to create GraphQL types based on TypeScript classes. TypeScript makes writing class-based OOP code intuitive. It provides us with classes, interfaces, etc. out of the box, which then afford us the opportunity to properly structure our code in a reusable manner, making it easy to maintain and scale.

This has led to the creation of tools and libraries that make it easier and faster to write applications that meet these expectations. TypeScript greatly benefits our productivity and experience as engineers.

Combining both TypeScript features and the benefits of GraphQL with the TypeGraphQL library, we are able to build resilient and strongly typed APIs that fulfill our needs in terms of maintenance, technical debt down the line, and so on.

As a final note, it would be great to explore other [advanced guides](https://typegraphql.com/docs/scalars.html) and [features](https://typegraphql.com/docs/dependency-injection.html) in the documentation to learn more about other aspects not covered in this tutorial. Also, it is an open-source project, which means you can have a peek at the [source code](https://github.com/MichalLytek/type-graphql/issues/168) as well 🙂.

Thanks for reading and reach out to me on my [Twitter](https://twitter.com/alex_nnakwue) if you have any questions.

* * *
## 200's only ‎✅: Monitor failed and show GraphQL requests in production 

While GraphQL has some features for debugging requests and responses, making sure GraphQL reliably serves resources to your production app is where things get tougher. If you’re interested in ensuring network requests to the backend or third party services are successful, [try LogRocket.](https://www2.logrocket.com/signup-lr)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/jd2amkhuiynfjf3i33qk.png)

[LogRocket](https://www2.logrocket.com/signup-lr) is like a DVR for web apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on problematic GraphQL requests to quickly understand the root cause. In addition, you can track Apollo client state and inspect GraphQL queries' key-value pairs.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. [Start monitoring for free.](https://www2.logrocket.com/signup-lr)
* * *

The post [Integrating TypeScript with GraphQL](https://blog.logrocket.com/integrating-typescript-graphql/) appeared first on [LogRocket Blog](https://blog.logrocket.com).