NestJS: What, Why, and How

25 / Sep / 2024 by Sushant Goyal 0 comments

Introduction

As the complexity of my Node.js projects increased, handling larger codebases got more difficult. The scaling process seemed sluggish and error-prone due to manual dependency wiring, fragmented structure, and a lack of robustness. Keeping clean, orderly codebases while incorporating additional libraries or services was difficult.

That’s when I explored NestJS, and it transformed my approach. Its seamless integration of TypeScript provided static typing and structure out of the box, making code easier to maintain. The well-organized architecture—controllers, services, and modules—immediately simplified my project structure.

The native dependency injection (DI) system was a game changer, handling external libraries and dependencies effortlessly. I no longer had to manually manage dependencies, allowing me to focus more on business logic. Unlike the manual setup required in Node.js, NestJS’s opinionated, full MVC framework gave me the structure and confidence to build scalable, maintainable applications. It became a modern, exciting alternative to my Node.js setups.

About NestJS

Server-side Node.js applications can be developed more efficiently and scalable with the help of the NestJS framework. Coders can develop programs in just JavaScript, but TypeScript is also fully supported and built-in. Because of its good library and tool integration, NestJS is a great option for both small projects and large business systems.

Read More: Implementing Role based Access Control in NestJS

Outstanding Features of NestJS

  • TypeScript at Its Core: NestJS is created with TypeScript, which provides developers with a well-structured codebase with high type safety. This greatly simplifies project management and scaling.
  • Modular Design: One of the highlights of NestJS is its modular architecture, which allows developers to break the app into smaller, more digestible modules. This makes the code not only easier to manage but also more organized.
  • Effortless Dependency Injection: NestJS simplifies the process of managing application components by offering a built-in Dependency Injection (DI) system. This also makes testing more straightforward.
  • Leverages Decorators: With the use of decorators, such as @Controller(), @Injectable(), and @Module(), developers can handle routing, dependency injection, and other operations clearly and concisely.
  • Multi-Platform Flexibility: NestJS gives the tools to develop WebSockets, microservices, RESTful APIs, and even GraphQL APIs without being limited to a single platform.
  • Highly Extensible: NestJS integrates seamlessly with popular third-party libraries like TypeORM, Mongoose, Passport, and many others, giving developers the flexibility to expand their application’s capabilities.

Why Choose NestJS?

Developers using Node.js to create server side applications mostly work with Express.js, a simple web framework that offers the essential functionality for creating APIs. However managing the codebase might get difficult as the application gets more complicated.

  1. Modularity and Structure
    Express.js: Offers middleware and routing functions, however, developers have to manually reorganize the structure as the application expands.
    NestJS: Comes with a built-in structure that fosters modularity. Large-scale applications benefit from improved maintainability as a result of the distinct division of responsibilities across controllers, services, and modules.
  2. TypeScript Support
    Express.js requires external packages for TypeScript support.
    NestJS: Designed with TypeScript in mind, it has built-in support for type safety, interfaces, and decorators.
  3. Dependency Injection (DI)
    Express.js: No built-in DI system; developers need to implement their own or use external libraries.
    NestJS: Provides a fully-fledged DI system, making testing easier and enabling better decoupling between different components of the application.
  4. Decorators and Metadata
    Express.js: Routing and middleware setup is done imperatively via methods like app.get(), app.post(), etc.
    NestJS: Uses decorators like @Controller(), @Get(), @Post(), and @Put() for declarative routing, making the code more readable and aligned with modern JavaScript paradigms.
  5. Interceptors, Guards, and Pipes
    Express.js: Middleware handles logic between requests and responses.
    NestJS: Introduces the concepts of interceptors (to transform response data), guards (for authorization checks), and pipes (for data validation and transformation), which offer more granular control over request/response handling.

Core Concepts in NestJS

Let’s explore some of the fundamental concepts of NestJS:

  1. Modules
    Modules are used to organize a NestJS application. Each module consists of controllers, providers, and other services organized logically within a set of code.

    import { Module } from '@nestjs/common';
    import { UsersController } from './users.controller';
    import { UsersService } from './users.service';
    @Module({
      controllers: [UsersController],
      providers: [UsersService], 
    })
    export class UsersModule {}
  2. Controllers
    Controllers are responsible for handling incoming requests and returning responses to the client.

    import { Controller, Get } from '@nestjs/common';
    @Controller('users')
    export class UsersController {
      @Get()
      findAll(): string {
        return 'This action returns all users';
      }
    }
  3. Services
    Services handle the application’s business logic. They can be integrated into controllers or other services.

    import { Injectable } from '@nestjs/common';
    @Injectable()
    export class UsersService {
      getUsers(): string[] {
        return ['User1', 'User2', 'User3'];
      }
    }
  4. Dependency Injection
    NestJS uses DI to provide services or other dependencies in controllers or services, reducing the coupling and making the application easier to maintain.

    import { Injectable } from '@nestjs/common';
    @Injectable()
    export class AppService {
      getHello(): string {
        return 'Hello World!';
      }
    }
    
    import { Controller, Get } from '@nestjs/common';
    import { AppService } from './app.service';
    @Controller()
    export class AppController {
      constructor(private readonly appService: AppService) {}
    
      @Get() getHello(): string {
        return this.appService.getHello();
      }
    }
  5. Middleware
    Middleware functions can be executed before a request reaches the route handler.

    import { Injectable, NestMiddleware } from '@nestjs/common';
    
    @Injectable()
    export class LoggerMiddleware implements NestMiddleware {
      use(req: Request, res: Response, next: Function) {
        console.log('Request...');
        next();
      }
    }

Building a Basic API

Step 1: Install NestJS CLI
npm install -g @nestjs/cli
nest new my-nest-app
Step 2: Create a Users Module
nest generate module users
Step 3: Create a Users Controller and Service
nest generate controller users
nest generate service users
Step 4: Implement CRUD in the Users Service
import { Injectable } from '@nestjs/common';
@Injectable()
export class UsersService {
  private readonly users = [];
  create(user) {
    this.users.push(user);
  }
  findAll(): string[] {
    return this.users;
  }
}
Step 5: Handle HTTP Requests in the Users Controller
import { Controller, Get, Post, Body } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}
  
  @Post()
  create(@Body() user: any) {
    this.usersService.create(user);
  }
  
  @Get()
  findAll(): string[] {
    return this.usersService.findAll();
  }
}
Step 6: Start the Application
npm run start

Conclusion

Developing a backend in NestJS makes Node.js projects more streamlined, scalable, and easier to develop. GraphQL apps, microservices, and RESTful APIs can be quickly and simply created on a dependable and intuitive platform using NestJS. Its use of decorators, modular architecture, and integrated TypeScript support make it groundbreaking for server-side programming.

We are a digital technology services company providing innovative product engineering solutions to diverse industries across the globe. We design and build digital platforms with Cloud, Data, and AI as the main pillars. Contact us and start your transformative journey today.

FOUND THIS USEFUL? SHARE IT

Leave a Reply

Your email address will not be published. Required fields are marked *