{{announcement.body}}
{{announcement.title}}

NestJS: A Backend NodeJS Framework

DZone 's Guide to

NestJS: A Backend NodeJS Framework

...

· Web Dev Zone ·
Free Resource

Last week an idea stuck my mind to explore the frameworks available in the NodeJS ecosystem to develop backend APIs. I had been using ExpressJS for a long time, and I thought it was about time to see what alternative frameworks were like.

I started listing down all the features that I wanted in a good NodeJS framework:

  • Easy to develop
  • Modularity
  • Integration with other applications
  • Extensibility
  • Maintainable
  • Performance
  • Easy to test and deploy
  • DevOps support ready
  • Support for microservices
  • REST and GraphQL

I took my special analyzer goggles, fuelled up my time machine, and started my journey to the future in search of a new framework. I went through frameworks like Koa, Hapi, Molecular, Seneca, etc. But none of them met all of my needs. Then, I saw NestJS.

Nest (NestJS) is a futuristic framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with and fully supports TypeScript (yet still enables developers to code in pure JavaScript), and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming). It is built on top of TypeScript, and a JavaScript version is also available. The framework is built by taking the concepts of Angular, and putting them on top of ExpressJS or Fastify.

Yes, you heard it right. I can change the underlying core framework to either Express or Fastify without changing any code. (Fastify has got a proven track record when it comes to performance.)

Let's have a look into how you can set up the NestJS.

You may also like: Nest.js Brings TypeScript to Node.js and Express, Part 1.

Installation

The installation is pretty straight forward. You can use npm/yarn to install the framework.

Shell
xxxxxxxxxx
1
 
1
npm i -g @nestjs/cli 
2
nest new my-first-project 


The cli will ask for the type of package system you want (npm/yarn). Once the installation is complete, you can start the application using the start script.

Shell
xxxxxxxxxx
1
 
1
cd my-first-project 
2
npm run start 


Open any browser and go to http://localhost:3000. You will now see a "Hello World!" message.

Hello, world with NestJs
Hello, World with NestJS

Hurray!

You can also use npm run start to start in the application in dev mode. This will watch for any changes in your code and restart the application accordingly.

First API

In most NodeJS backend frameworks, when writing an API, we will create a callback method for the defined URL. This is not the case in NestJS.

If you have a Angular/Spring Boot background, you will find the below features very familiar. 

In NestJS, in order to create an API, we need a controller, which is similar to a component in Angular (or a RestController in Springboot).

Let's say I need to create a time API that returns the current server time. Run the following CLI command inside your project directory to create a new controller:

Shell
xxxxxxxxxx
1
 
1
nest g controller time


This will create two files. The time.controller.spec.ts is the test file and time.controller.ts is our main file

Shell
xxxxxxxxxx
1
 
1
CREATE /src/time/time.controller.spec.ts (479 bytes) 
2
CREATE /src/time/time.controller.ts (97 bytes) 
3
UPDATE /src/app.module.ts (322 bytes) 


You can see that it updates the app.module.ts file to add the reference to the new controller, time.controller. This is similar to bootstrapping a component in Angular.

This is how the folder structure currently looks: 

Current folder structure

Current folder structure

Hurray

Open the time.controller.ts file and replace the code with the following block:

TypeScript
xxxxxxxxxx
1
12
 
1
import { Controller, Get } from '@nestjs/common';
2
 
          
3
@Controller('time')
4
export class TimeController {
5
    @Get()
6
    getTime(): any {
7
      return {
8
          time : new Date(),
9
      };
10
    }
11
}
12
 
          


Restart the application (if you had started in dev mode, it will restart automatically), and access http://localhost:3000/time using Postman/browser /curl.

You will now see the following JSON response.

JSON
xxxxxxxxxx
1
 
1
{
2
  "time": "2019-12-31T05:06:31.805Z"
3
}


If you gave an argument in the @Get decorator, then the API URL will change accordingly. So, the effective URL of an API  should be "API" + @Controller's URL + @Get's URL.

Similar to @Get, NestJS also supports other REST verbs, like @Post@Put@Update@Delete, etc. Whatever object is returned from the method is sent back to the client as the result of the API. You can get more details about the controller implementation at https://docs.nestjs.com/controllers.

This is one of the simplest API implementations in NodeJS, similar to Java's Spring Boot implementation.

Exception Handling

In NodeJS, we use try/catch or exception middleware to handle the errors in the application. But, in NestJS, the approach is unique. You can create a filter class that can handle the specific exceptions.

TypeScript
xxxxxxxxxx
1
20
 
1
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
2
import { Request, Response } from 'express';
3
 
          
4
@Catch(HttpException)
5
export class HttpExceptionFilter implements ExceptionFilter {
6
  catch(exception: HttpException, host: ArgumentsHost) {
7
    const ctx = host.switchToHttp();
8
    const response = ctx.getResponse<Response>();
9
    const request = ctx.getRequest<Request>();
10
    const status = exception.getStatus();
11
 
          
12
    response
13
      .status(status)
14
      .json({
15
        statusCode: status,
16
        timestamp: new Date().toISOString(),
17
        path: request.url,
18
      });
19
  }
20
}


This means if an HttpException is thrown from any part of the application, this filter is triggered, the logic executes, and a response is sent back to the client.

Easy? Huh? You can find more details at https://docs.nestjs.com/exception-filters.

Guards

Security is very critical. Typically in an ExpressJS application, we use middleware to check for the authorization level of an API. In NestJS, we can use guards instead.

TypeScript
xxxxxxxxxx
1
12
 
1
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
2
import { Observable } from 'rxjs';
3
 
          
4
@Injectable()
5
export class RolesGuard implements CanActivate {
6
  canActivate(
7
    context: ExecutionContext,
8
  ): boolean | Promise<boolean> | Observable<boolean> {
9
    return true;
10
  }
11
}
12
 
          


and in the controller:

TypeScript
xxxxxxxxxx
1
 
1
@Controller('cats')
2
@UseGuards(RolesGuard)
3
export class CatsController {}


You can also create global guards in app.module.ts

TypeScript
xxxxxxxxxx
1
 
1
const app = await NestFactory.create(AppModule);
2
app.useGlobalGuards(new RolesGuard());


Microservices Support

One of the biggest advantages of this framework is its out-of-the-box support for microservices and transport layers. It has support for different transport layers, like TCP, gRPC, MQTT, RabbitMQ, etc.

You can read more about microservices in NestJS @ https://docs.nestjs.com/microservices/basics.

GraphQL

NestJS has out-of-the-box support for GraphQL. To start, install the GraphQL support package:

Shell
xxxxxxxxxx
1
 
1
npm i --save @nestjs/graphql apollo-server-express graphql-tools graphql 


NestJS offers two methods for integrating GraphQL:

  1. Schema first: where the definition is written in GraphQL Schema Definition Language (SDL).
  2. Code first: where we use decorators to generate the GraphQL schema.

You can read more about GraphQL integration @ https://docs.nestjs.com/graphql/quick-start.

Express and Fastify

Another impressive feature of NestJS is that it can run on top of Express or Fastify frameworks, and you don't have to change your API's code for this. If you want to access any native framework features of Express or Fastify, it's pretty simple.

By default, NestJS uses Express. If you want to use Fastify, then you can install the package for Fastify, like so: 

Shell
xxxxxxxxxx
1
 
1
npm i --save @nestjs/platform-fastify 


Benchmark results show that Fastify has superior performance when compared to Express.

More Goodies

NestJS also has out-of-the-box support for Swagger, Jest, Supertest, TypeORM, Sequelize, Terminus, Compodoc, Custom decorators and lots more...

Wrapping Up

IMHO NestJS is a framework that can be used in small backend applications to large enterprise-level applications. It helps you in building an efficient, scalable application. The maintainability of this framework is huge compared to other NodeJS frameworks.

I've seen projects using ExpressJS, where the code maintainability has become a serious concern after a few months of development. The ability to switch Express and Fastify is one of the cool features of NestJS.

Head on to https://nestjs.com to start developing your app.

Happy Coding!


Further Reading

Topics:
nodejs ,framework ,web dev ,express ,typescript ,javascript

Published at DZone with permission of Vinod Surendran . See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}