Building Modern Nodejs Application using Nestjs and TypeScript

In this article, we will see how to build REST API using Nestjs with TypeScript. Building Modern Nodejs Application using Nestjs and TypeScript

Recent Articles,

How to Run MongoDB as a Docker Container in Development

TypeScript Basics – The Definitive Guide

Crafting multi-stage builds with Docker in Node.js

Nestjs is a framework for building efficient,scalable node.js server side applications.

Under the hood, Nest makes use of robust HTTP Server frameworks like Express (the default) and optionally can be configured to use Fastify as well!

Why NestJS

Nest provides an out-of-the-box application architecture which allows developers and teams to create highly testable, scalable, loosely coupled, and easily maintainable applications.

it provides design patterns out-of-the-box which helps to develop scalable application.

Resources

Here, i will mention some of the good resources that you can follow to get deep dive into nestjs

Setting up NestJS

First install nestjs globally on your machine to use the nestjs cli in your machine.

1 npm i -g @nestjs/cli

now, you can able to use nest command globally. After that, you can create a new nestjs project using the command.

1 nest new rest-nest-api

it will create a project scaffold. it will create lot of files for us to save time.

Project Structure

there are bunch of files that are predefined here. let's try understand one by one.

First and foremost, you can see a file main.ts in the application. it is a main entrypoint for an application.

1 import { NestFactory } from "@nestjs/core" 2 import { AppModule } from "./app.module" 3 4 async function bootstrap ( ) { 5 const app = await NestFactory . create ( AppModule ) 6 await app . listen ( 3000 ) 7 } 8 bootstrap ( )

it will take the file app.module and create server instance by calling NestFactory.create and start running server on PORT 3000. we can change the port if we want to.

Module

After that, app.module.ts. it will contains the group of components such as controller,services for the particular domain.

For Example, if we are designing REST API to handle User, User controller and User Service will be grouped in the user.module.ts and will be used in all other places.

app.module.ts will contain the App Controller and App Service

1 import { Module } from "@nestjs/common" 2 import { AppController } from "./app.controller" 3 import { AppService } from "./app.service" 4 5 @ Module ( { 6 imports : [ ] , 7 controllers : [ AppController ] , 8 providers : [ AppService ] , 9 } ) 10 export class AppModule { }

Controller

Controller handles all the request and response and Service will have all the interaction between DB and controller.

1 import { Controller , Get } from '@nestjs/common' ; 2 import { AppService } from './app.service' ; 3 4 @ Controller ( ) 5 export class AppController { 6 constructor ( private readonly appService : AppService ) { } 7 8 @ Get ( ) 9 getHello ( ) : string { 10 return this . appService . getHello ( ) ; 11 } 12 }

AppController will have decorator @Controller based on that nestjs identifies the controller and services.

we have method called @Get decorator which tells that it is a get method. if you pass the prefix in the @Controller,it will handle that particular route.

For example, if you want to handle the /user routes in the UserController, you can pass 'user' in the controller like @Controller('user).

Each method decorator such as @Get,@Post and @Put in UserController will be added with a prefix.

Services

Services will be injected to the controller. Service contains all the Database queries.

1 import { Injectable } from "@nestjs/common" 2 3 @ Injectable ( ) 4 export class AppService { 5 getHello ( ) : string { 6 return "Hello World!" 7 } 8 }

let's run the application. To run it, we can use the command

1 npm run start:dev

you can see the application running in terminal like

you can visit the url http://localhost:3000

Let's Build Some REST API

Let's create a CRUD for todo application in nestjs. Before starting to create a api for a domain, remember the flow of nest js.

Firstly, create a service for todo domain. you can generate the service using the following command,

1 nest generate service todos

After that, create a controller file using the following command,

1 nest generate controller todos

Once those files are created, it will be added into app.module.ts automatically.

Now, it is time to write some API for our application. To get all the todos data, we need a get request.

First create a get method in the todos.service.ts

1 todos = [ { id : 1 , name : 'Complete' } , { id : 2 , name : 'Check' } ] ; 2 3 getTodos ( ) { 4 return this . todos ; 5 }

Once you add the function in service, import service in the controller to use that function.

1 constructor ( private todosService : TodosService ) { }

Now, you can able to call the get method in the controller

1 @ Get ( ) 2 getTodos ( ) { 3 return this . todosService . getTodos ( ) ; 4 }

it will return all the todos in the get request. you can verify it by running the application.

Likewise, we will add the other api request such as POST,PUT and DELETE.

todos.controller.ts

1 import { 2 Controller , 3 Get , 4 Param , 5 Post , 6 Body , 7 Put , 8 Delete , 9 } from '@nestjs/common' ; 10 import { TodosService } from './todos.service' ; 11 12 interface todosDto { 13 id : string ; 14 name : string ; 15 } 16 17 @ Controller ( 'todos' ) 18 export class TodosController { 19 constructor ( private todosService : TodosService ) { } 20 21 @ Get ( ) 22 getTodos ( ) { 23 return this . todosService . getTodos ( ) ; 24 } 25 26 @ Get ( ':id' ) 27 getTodo ( @ Param ( ) params ) { 28 console . log ( 'id' , params . id ) ; 29 return this . todosService . getTodos ( ) . filter ( t => t . id === params . id ) ; 30 } 31 32 @ Post ( ) 33 addTodo ( @ Body ( ) todo : todosDto ) { 34 console . log ( 'todo' , todo ) ; 35 this . todosService . addTodo ( todo ) ; 36 } 37 38 @ Put ( ) 39 updateTodo ( @ Body ( ) todo : todosDto ) { 40 console . log ( 'update todo' , todo ) ; 41 this . todosService . updateTodo ( todo ) ; 42 } 43 44 @ Delete ( ) 45 deleteTodo ( @ Body ( ) todo : todosDto ) { 46 console . log ( 'delete todo' , todo . id ) ; 47 this . todosService . deleteProduct ( todo . id ) ; 48 } 49 }

todos.service.ts

1 import { Injectable } from "@nestjs/common" 2 3 @ Injectable ( ) 4 export class TodosService { 5 todos = [ 6 { id : 1 , name : "Complete" } , 7 { id : 2 , name : "Check" } , 8 ] 9 getTodos ( ) { 10 return this . todos 11 } 12 13 addTodo ( todo ) { 14 this . todos = [ ... this . todos , { ... todo } ] 15 } 16 17 updateTodo ( todo ) { 18 this . todos = this . todos . map ( t => { 19 if ( t . id == todo . id ) { 20 return { ... todo } 21 } 22 return t 23 } ) 24 } 25 26 deleteProduct ( id ) { 27 this . todos = this . todos . filter ( t => t . id != id ) 28 } 29 }

After adding the following code, we can able to add todo and update it using the api's. you may noticed that i used interface in the controller.

NestJs uses interface to model the data use to check the type of data in the POST Body and other places also.

Basically, it is a common pattern that is used in Nestjs Application development

Summary

To conclude, this summarizes the basic concepts to run the Nestjs application and Building Modern Nodejs Application using Nestjs and TypeScript .

we will see some advanced concepts of Nestjs in upcoming articles.

Recommended Course to Learn TypeScript : Stephen grider's TypeScript Course

To Read More