How to fly with Nest.js development
Tags: nestjs
Published: 2019-09-03 16:10:27

This article will show you how you can add database migrations, and data  seeding, into your Nest.js application, and gain a super-fast development initiation phase.

Nest.js is a progressive Node.js Web Framework that provides you with a robust backend for your frontend applications. It is highly comparable to Angular in terms of concepts like Module, Provider, etc. and is a clear choice by Angular developers.

If you are interested, read more about Nest.js at:

- [Nest.js official documentation](https://docs.nestjs.com)
- [Step by step guide to Nest.js](https://www.codemag.com/Article/1907081/Nest.js-Step-by-Step)

The source code of this article is available at this GitHub [repo](https://github.com/bhaidar/seeding-migration-typeorm).

Let's start by creating the application.

##Create a Full-Stack app with Angular CLI
In this section, I will create a full-stack application, using the [Angular CLI](https://cli.angular.io), with the support of the [Nest.js ng-universal](https://github.com/nestjs/ng-universal) library. 

###Basic Prerequisites
- [Node.js](https://nodejs.org/en/) v10.16.2
- [Docker v19.03](https://docs.docker.com/docker-for-mac/)
- Code editor (Visual Studio Code, Sublime, etc.)

###Add an Angular app
Install the latest version of the Angular CLI globally by running the commands:

```bash
npm uninstall -g @angular/cli
npm cache clean --force
npm install -g @angular/cli@latest
```

Now that you have installed the Angular CLI, let's create our Angular app by running this command:

`ng new seeding-migration-typeorm`

The `ng new` command asks you several questions as shown in Figure 1:

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

- Whether you want to use Angular routing?
- What style sheet format would you like to use?

After you make your selection, the Angular CLI starts scaffolding your application.

Once finished, open it in your preferred code editor, navigate to the `package.json` file, and change the `start` NPM script to look like this:

`"start": "ng serve -o"`

Let's take a squeeze, and run the application to make sure it works. Run the following command to start the application:

`npm start`

This command, which finishes building the application, opens a new browser instance, and runs the application as shown in Figure 2 below:

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

This is the new home page that the latest Angular CLI generates. Now let's focus on adding a backend Nest.js application.
Add a Nest.js app

The correct location to create a backend Nest.js application is inside the Angular root folder. The other option is to create it outside the Angular application, but to do so would be a nightmare! It is almost impossible to manage both with two separate `package.json` files. It's not recommended.

Nest.js provides the [Angular Universal module for Nest framework](https://github.com/nestjs/ng-universal) that manages all the nifty little details of creating a new Nest.js application, and integrating it with the Angular CLI system.

Run the following schematic to create your Nest.js application:

`ng add @nestjs/ng-universal`

The schematic starts by installing the latest version of the `@nestjs/ng-universal` NPM package. It then prompts you for the client's app name. In this case, you type `seeding-migration-typeorm`.

This command creates a new Nest.js application inside of a new folder named `server`, and is placed at the root folder of the Angular app.

The command added a few NPM scripts into the `package.json` file, allowing you to compile, and run the new server app. In addition, it amends the `angular.json` file to add a new `Architect Target` name `server`.

Now, the easiest way to run this full-stack application with a live-reloading feature is to execute the following command:

`npm run serve`

Both the Angular and Nestjs apps would run on <strong>Port 4200</strong>. However, to access any Nest.js Controller endpoint, you will have to suffix the base URL with `/api`. The Nest.js backend API becomes available at `http://localhost:4200/api`.

##Setup a PostgreSQL database with Docker
To demonstrate seeding, and migrations, we need to connect our backend application to a database engine.

For this article, I've chosen to use the [PostgreSQL](https://www.postgresql.org) database engine or "Postgres". I will run an instance of PostgreSQL using a [PostgreSQL Docker](https://hub.docker.com/_/postgres) container, which I believe, is the cleanest, and easiest way to add a PostgreSQL database instance to your application.

Start by creating a new `docker-compose.yml` at the root of the Angular app and paste the following content inside it:

```yaml
version: '3'
services:
  db:
    container_name: typeormseed_db
    image: postgres:10.7
    volumes:
      - './db/initdb.d:/docker-entrypoint-initdb.d'
    ports:
      - '5432:5432'
```

This docker-compose file instructs Docker to create a new Postgres Docker container with the following settings:

- The container name is <strong>typeormseed_db</strong>
- The Postgres Docker image <strong>postgres:10.7</strong>
- Create a new volume by mapping the physical folder named <strong>db\initdb.d</strong> to an internal folder inside the image. I will place an initialization script inside this folder so that Docker can run the first time it creates the Postgres container.
- Finally, you expose the Postgres instance to the host machine by mapping its internal port to a port used on the host machine.

Now let's create a new folder named `db` at the root level of the Angular app. Then, create a subfolder named `initdb.d`. Then, inside this folder, create a new bash script file named `initdb.sh`. Place the following content inside this new file:

```bash
#!/usr/bin/env bash
 
set -e
 
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
	CREATE USER typeormseed_user;
	CREATE DATABASE typeormseed ENCODING UTF8;
	GRANT ALL PRIVILEGES ON DATABASE typeormseed TO typeormseed_user;
 
	ALTER USER typeormseed_user WITH PASSWORD 'password123';
	ALTER USER typeormseed_user WITH SUPERUSER;
EOSQL
```
The first time Docker creates the Postgres container, it will run this script. It will then create a new Postgres database instance named <strong>typeormseed</strong>, a new database user named <strong>typeormseed_user</strong>, and finally gives the proper permissions for this user to run, and access, this database.

In addition, you need to add a new NPM script to the `package.json` file to make it easier when you run Docker, and instantiate a Postgres container.

Add the following script under the `script` node inside the `package.json` file:

`"run:db": "docker-compose up -d && exit 0"`

Finally, run the following command to start the container:

`npm run run:db`

This command will create the Postgres container in a detached mode. 

Now that the Postgres database is up and running, let's move on and continue adding more features.

###Add TypeORM module
[TypeORM](https://typeorm.io) is an Object Relational Mapping (ORM) library written in JavaScript and is capable of connecting to a variety of database engines including PostgreSQL, MySQL, Maria DB, MongoDB and much more.

Nest.js fully supports this library and provides the [@nestjs/typeorm](https://github.com/nestjs/typeorm) package as a wrapper around the TypeORM library to effortlessly integrate with the Nest.js Dependency Injection System.

> You can consult the Nest.js official documentation on [Working with databases in Nest.js](https://docs.nestjs.com/techniques/database).

> You can also read a more detailed explanation on TypeORM, how Nest/js integrates with this library and examples on using them together by checking my article on [Nest.js Step by Step Guide - Databases](https://www.codemag.com/Article/1909081/Nest.js-Step-by-Step-Part-2).

To start using TypeORM in the Nest.js application, we need to install a few NPM packages. Run the command:

`npm install @nestjs/typeorm typeorm pg`

- The `@nestjs/typeorm` package represents the Nest.js wrapper over TypeORM.
- The `typeorm` package is the official TypeORM library package.
- The `pg` package is the official connector library for Postgres.

Let’s import the `TypeOrmModule` inside the `server/app.module.ts` as follows:

```typescript
import { Module } from '@nestjs/common';
import { AngularUniversalModule } from '@nestjs/ng-universal';
import { join } from 'path';

import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    AngularUniversalModule.forRoot({
      viewsPath: join(process.cwd(), 'dist/browser'),
      bundle: require('../server/main'),
      liveReload: true
    }),
    TypeOrmModule.forRoot()
  ]
})
export class ApplicationModule {}
```

Next, create a new `ormconfig.json` file at the root of the Angular app, and paste the following content inside it:

```json
{
  "type": "postgres",
  "host": "localhost",
  "port": 5432,
  "username": "typeormseed_user",
  "password": "password123",
  "database": "typeormseed",
  "entities": ["dist/**/*.entity.js"],
  "migrations": ["dist/server-app/migration/**/*.js"],
  "synchronize": false,
  "cli": {
    "entitiesDir": "server",
    "migrationsDir": "server/migration"
  }
}
```

At runtime, the `TypeOrmModule` class loads the configuration settings from the `ormconfig.json` file, and creates a TypeORM database connection to the Postgres database instance.

That’s it! 

##Build the Blog API
Now that the full-stack application is up and running with an active connection to the database, it’s time to start building the Blog API. 

This next section is a step by step on how to:
- Add a new module in Nest.js 
- Add model objects 
- Generate, and run migrations 
- Create migrations, and seed data 
- Add a Nest.js service 
- Add a Nest.js controller to test the application.

Let’s get started.

###Add Blog module
Nest.js framework offers the Nest.js CLI. This component is similar to Angular CLI, or other CLI. The goal of the CLI, is to increase productivity by enhancing the software development process, and make it easier on the developer to add new Nest.js artifacts to the application.

Install the Nest.js CLI globally on your machine by running:

`npm install -g @nestjs/cli`

Back to the application, change directory `cd` to the `server` folder, and run the following command to scaffold a Blog Nest.js module:

`nest g module blog --no-spec`

The command creates a new blog module under the path `/server/src/blog`. In addition, it also imports this module into the main `app.module.ts` file.
Add model objects
We will create the Blog and BlogPost entity objects. Run the following command to create the two classes together:

`touch src/blog/post.entity.ts src/blog/comment.entity.ts`

Paste this code inside the `blog/post.entity.ts` file:

```typescript
import { Entity, PrimaryGeneratedColumn, Column, OneToMany } from 'typeorm';
import { Comment } from './comment.entity';

@Entity()
export class Post {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('varchar')
  title: string;

  @Column('text')
  content: string;

  @Column({ type: 'varchar', nullable: true })
  tags: string;

  @Column({ name: 'created_at', default: () => `now()`, nullable: false })
  createdAt: Date;

  @Column({ name: 'updated_at', default: () => 'now()', nullable: false })
  updateTime: Date;

  @OneToMany(type => Comment, comment => comment.post, {
    primary: true,
    cascade: ['insert']
  })
  comments: Comment[];
}
```

The file defines the `post` entity to use to create a new post in the blog engine. It defines a one-to-many relation with the `comment` entity.

Paste the following inside the `blog/comment.entity.ts` file:

```typescript
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm';
import { Post } from './post.entity';

@Entity()
export class Comment {
  @PrimaryGeneratedColumn()
  id: number;

  @Column('text')
  content: string;

  @Column({ type: 'varchar', nullable: false })
  author: string;

  @Column({ type: 'varchar', nullable: false })
  email: string;

  @Column({ name: 'created_at', default: () => `now()`, nullable: false })
  createdAt: Date;

  @ManyToOne(type => Post, post => post.comments, {
    primary: true,
    cascade: ['insert']
  })
  post: Post;
}
```

The `comment` entity represents a single comment on a blog post. It defines a many-to-one relation with the `post` entity.

As a final step, let’s configure the `TypeOrmModule` with these entities at the level of the `blog.module.ts` file as follows:

```typescript
@Module({
  imports: [TypeOrmModule.forFeature([Post, Comment])]
})
export class BlogModule {}
```

The `TypeOrmModule` will be able to generate custom repository classes for those entities, and make them available via the Nest.js Dependency Injection System as you will see shortly.
Generate, and run a migration
Now that the entities are ready, let’s generate a new migration with TypeORM. 

A TypeORM single migration has two functions, up() and down(), that hold the code for a migration. The up() function runs when running a migration against the database, and usually contains code to create, or alter stuff, in the database. While the down() function runs when undoing a migration.

```typescript
import { MigrationInterface, QueryRunner } from 'typeorm';

export class INITIALDB1566761690370 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<any> {}
  public async down(queryRunner: QueryRunner): Promise<any> {}
}
```
Start by building, and compiling the application, by running the following command:

```bash
npx tsc -p server/tsconfig.json
npm run serve
```

Run the next command to create our first migration. Make sure the Postgres container is up and running.

`npx typeorm migration:generate --name=INITIAL_DB`

This command uses the TypeORM CLI to generate a new migration. It compares the state of the database with the entities it finds in the application, and generates the migration accordingly.

When you finish running this command, navigate to `server/migration` folder, and locate the new migration file there. It hosts the following migration content:

```typescript
// 1566761690370-INITIAL_DB.ts

import { MigrationInterface, QueryRunner } from 'typeorm';

export class INITIALDB1566761690370 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<any> {
    await queryRunner.query(
      `CREATE TABLE "post" ("id" SERIAL NOT NULL, "title" character varying NOT NULL, "content" text NOT NULL, "tags" character varying, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "updated_at" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_be5fda3aac270b134ff9c21cdee" PRIMARY KEY ("id"))`
    );
    await queryRunner.query(
      `CREATE TABLE "comment" ("id" SERIAL NOT NULL, "content" text NOT NULL, "author" character varying NOT NULL, "email" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "postId" integer NOT NULL, CONSTRAINT "PK_f685613ae59fda2ac1e490c9189" PRIMARY KEY ("id", "postId"))`
    );
    await queryRunner.query(
      `ALTER TABLE "comment" ADD CONSTRAINT "FK_94a85bb16d24033a2afdd5df060" FOREIGN KEY ("postId") REFERENCES "post"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`
    );
  }

  public async down(queryRunner: QueryRunner): Promise<any> {
    await queryRunner.query(
      `ALTER TABLE "comment" DROP CONSTRAINT "FK_94a85bb16d24033a2afdd5df060"`
    );
    await queryRunner.query(`DROP TABLE "comment"`);
    await queryRunner.query(`DROP TABLE "post"`);
  }
}
```

The up() function shows the SQL code to create the two tables `post`, and `comment`. Also, it shows the code that alters the `comment` table to add a Foreign Key to the `post` Primary Key.

Once again, run the following command to build and compile the application:

`npm run serve`

Let's run the migration and create the corresponding tables in the database. Issue the following command:

`npx typeorm migration:run`

The command collects all the migrations that haven't been applied before on the database, and executes their up() function. In this case, we only have one migration to run.

The command creates the two tables and configures the relation between them.

To verify the migration, run:

`npx typeorm query "SELECT * FROM post"`

The result is the following:

```bash
Running query: SELECT
Query has been executed. Result: 
[]
```

The table is found but contains 0 records.

###Seed data using migrations
So far you've seen how to generate a migration with TypeORM. 

Now the plan is to use TypeORM to create a new empty migration. Then, we will fill this new migration with the code required to insert some static data. When the migration is ready, we will use the TypeORM CLI to run the migration against the database and seed the data into the tables.

This is how you would go about adding the seed data into the database using TypeORM.

Let's begin!

Run the command:
`npx typeorm migration:create --name SEED_DATA`

Replace the content of this file with the following:

```typescript
import { MigrationInterface, QueryRunner, getRepository } from 'typeorm';
import { Post } from '../src/blog/post.entity';
import { Comment } from '../src/blog/comment.entity';

export class SEEDDATA1566763187470 implements MigrationInterface {
  public async up(queryRunner: QueryRunner): Promise<any> {
    // create a post
    const post = getRepository(Post).create({
      title: 'Seeding data to database with TypeORM',
      content:
        'In this post, I will walk you through a step by step guide on how to seed data to database.'
    });

    await getRepository(Post).save(post);

    // create a comment
    const comment1 = getRepository(Comment).create({
      content: 'Nice job!',
      author: 'Jim Jones',
      email: 'jim.jones@myemail.com',
      post
    });

    // create a comment
    const comment2 = getRepository(Comment).create({
      content: 'Informative blog post!',
      author: 'Bin Nadal',
      email: 'bin.nadal@myemail.com',
      post
    });

    await getRepository(Comment).save(comment1);
    await getRepository(Comment).save(comment2);
  }

  public async down(queryRunner: QueryRunner): Promise<any> {}
}
```

The code uses the `getRepository(post)` function to get access to a repository instance for the `post` entity. Then, it uses the repository `create()` function to create a new post object together with the comments on this post.

It then uses the repository `save()` function to save the changes to the database.

To verify the results, run the following command:

```bash
npx typeorm migration:run
npx typeorm query "SELECT * FROM post"
```

The query results in the following:

```bash
Running query: SELECT * FROM post
Query has been executed. Result: 
[
  {
    "id": 1,
    "title": "Seeding data to database with TypeORM",
    "content": "In this post I will walk you through a step by step guide on how to seed data to database.",
    "tags": null,
    "created_at": "2019-08-25T17:39:11.917Z",
    "updated_at": "2019-08-25T17:39:11.917Z"
  }
]
```

There is a single post that exists in the database, and has an `id = 1`.

Let's also query for the comments by running the following command:

`npx typeorm query "SELECT * FROM comment"`

The query results in the following:

```bash
Running query: SELECT * FROM comment
Query has been executed. Result: 
[
  {
    "id": 1,
    "content": "Nice job!",
    "author": "Jim Jones",
    "email": "jim.jones@myemail.com",
    "created_at": "2019-08-25T17:39:11.953Z",
    "postId": 1
  },
  {
    "id": 2,
    "content": "Informative blog post!",
    "author": "Bin Nadal",
    "email": "bin.nadal@myemail.com",
    "created_at": "2019-08-25T17:39:11.974Z",
    "postId": 1
  }
]
```

Both comment objects were created with the `postId = 1`. All is working great!

This method of seeding data to a database with TypeORM using a migration is the best option available for you in the time being to populate your database with data during the development life cycle of your application.

###Add the Blog service

Let's create the Blog service, and define functions to query for posts, and comments.

Change directory `cd server` to the server directory, and run the following command:

`nest generate service blog --no-spec`

This command creates the `blog.service.ts` file inside the `blog` folder and also adds this service as a provider on the `blog.module.ts`. This last step makes the `BlogService` available via the Nest.js Dependency Injection System.

Replace the content of this service with the following code:

```typescript
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Post } from './post.entity';
import { Repository } from 'typeorm';

@Injectable()
export class BlogService {
  constructor(
    @InjectRepository(Post)
    private repo: Repository<Post>
  ) {}

  async findAll(): Promise<Post[]> {
    return await this.repo.find({ relations: ['comments'] });
  }
}
```

The `BlogService` is decorated with `@Injectable()` decorator. This tells the framework that this service is expecting to receive dependencies through its constructor.

The service constructor injects a custom repository class for `Post` entity. The `@nestjs/typeorm` package is responsible for generating those custom repositories for all entities that we have already defined on the `blog.module.ts` by importing the `TypeOrmModule.forFeature([Post, Comment])`.

The service defines a single `findAll()` function that returns all posts stored in the database and eagerly loads their related comment objects too.

###Add Controller
Now let's expose a Blog API Controller endpoint to allow client apps to request this data.

Change directory to the server folder `cd server`, and run the following command:

`nest generate controller blog --no-spec`

The command creates the `BlogController` class inside the `blog/blog.controller.ts` file, and also imports the controller into the `controllers` property of the `blog.module.ts` module. This last step makes the `BlogController` available via the Nest.js Dependency Injection System.

Replace the content of this controller with the following code:

```typescript
import { Controller, Get, Req } from '@nestjs/common';
import { BlogService } from './blog.service';
import { Post } from './post.entity';

@Controller('blog')
export class BlogController {
  constructor(private readonly blogService: BlogService) {}

  @Get()
  async findAll(@Req() req: any): Promise<Post[]> {
    return await this.blogService.findAll();
  }
}
```

The `BlogController` class is decorated with the `@Controller()` decorator.

The constructor accepts a `BlogService` instance. The Nest.js Dependency Injection System creates, and provides, this controller a `BlogService` instance at run time.

This controller defines a single action designated by `@Get()` decorator to say that this action is accessed via a GET request. This action delegates the call to the `BlogService` to query for all post data in the database, and return them back in a response to the client request.
Let’s run the application and access this controller endpoint via the browser. Run the following command:

`npm run serve`

Navigate to the browser and type in the URL `http://localhost:4200/api/blog` and you shall see something similar to Figure 3 below:

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

##Test with Postman
Let's test the `BlogController` using Postman this time. 

With Postman, you can simulate a browser by sending HTTP requests, and receiving HTTP responses. 

If you want to learn more about Postman, you can check my complete guide on Postman for busy developers.

Make sure the app is up and running, open Postman, and send a GET request to the URL `http://localhost:4200/api/blog` as shown in Figure 4 below:

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

##Conclusion
At the beginning of every new project, you will be busy putting together the foundations of the application, building dummy interfaces to start showing the client, and getting some feedback. You won’t have enough time to build full services on the backend that provide all the CRUD (Create Read Update and Delete) operations right from the beginning to enable you to add data, and use it for testing purposes. 

Using the TypeORM migrations to seed data into the database is a neat and quick workaround to get you started quickly.  The added benefit of using these migrations is that they do not waste time on unnecessary activities in the early stages of the application.


This post was written by [Bilal Haidar](https://www.bhaidar.dev/), a mentor with [This Dot](https://thisdot.co/).

*You can follow him on Twitter at [@bhaidar](https://twitter.com/bhaidar).*

*Need JavaScript consulting, mentoring, or training help? Check out our list of services at [This Dot Labs](https://thisdot.co).*