NestJS Typescript: The Ultimate Guide (2022)

  • NestJS Typescript: The Ultimate Guide (2022)

    Sharing is Caring... Show some love :)

    This is the most comprehensive guide on the NestJS typescript framework online.

    1. Complete NestJS Overview
    2. NestJS: The Framework
    3. Building with NestJS
    4. Advanced NestJS Guide

    Prerequisites

    Before continuing with this guide, you will need to understand what server-side web programming, frameworks, general Knowledge of JavaScript, TypeScript, and NodeJS are, which will aid your understanding of the NestJS framework.

    Typescript: The Complete Developer’s Guide is my all-time TypeScript best course. You will master Typescript by learning popular design patterns and building complex projects with it. Includes React and Express!

    Complete NestJS Overview

    This guide will learn a fascinating framework in the Node.js and TypeScript ecosystem.

    You will learn the Nestjs typescript framework from scratch to an advanced level and how to install Node.js and set up the NestJS server in your local machine.

    Also, you will learn how to connect a MongoDB database with NestJS and build and deploy a full-blown application to the server.

    Let’s dive right in:

    A portfolio builder for tech writers

    What is NestJS?

    NestJS has proven to be the fastest-growing TypeScript framework for building flexible, scalable, large-scale, and enterprise-ready backend applications using Node.js. 

    When building highly testable, well-structured, and maintainable backend applications using TypeScript, NestJS is the top choice for top organizations.

    NestJS has over 39,000 GitHub Stars and 3,900 Forks on Github at the time of writing.

    A weekly download of up to 700,000 over the last 6-months from NPMTrends makes Nest.js framework a goto framework for crafting out your backend project with Node.js and TypeScript.

    As a complete web framework with high structure and well-structured architectures, the NestJS typescript framework has great features that make it scalable, testable, and maintainable.

    Let’s dive into them:

    Features of NestJS

    TypeScript

    NestJs is built with TypeScript, and it’s the most popular in this ecosystem. 

    This integration drastically reduces the errors involved with Type-checking and Type inconsistencies when using JavaScript to build large-scale and enterprise applications.

    CLI

    NestJS provides the most powerful CLI tool. The tool can create and manage any part of the NestJS framework by typing in your terminal commands. 

    The CLI is a single point of truth for command freaks to develop applications with NestJS without much of the GUI interactions.

    With the CLI, you can create databases to create modules, controllers, and services files by typing in a few commands.

    Documentation

    NestJS provides very clean and well-documented guides for beginners to build simple to complex applications with the NestJS typescript framework.  

    With the documentation, it’s straightforward to get started, and almost all your development questions have already been covered in the documentation.

    Microservices

    Aside from the traditional architectural style of development called Monolithic.

    NestJS natively supports the microservice architectural development style right out of the box by providing proper integration to many popular microservice tools such as Kafka, gPRC, RabbitMQ, etc.

    Popular Libraries

    NestJS supports different popular tools out of the box, which lessens development hassles and increases faster application development. The best developer tools are already integrated, following best practices and industry standards.

    NestJS supports TypeORM, Mongoose, GraphQL, Logging, Validation, Caching, WebSockets, and much more right out of the box, and no extra configuration is needed.

    Aside from these general features of NestJS, many great features come with using NestJS for your project that we didn’t list out.

    Why you should learn NestJS

    Doubting a new framework happens to everyone first. At least it happens to me.

    It is most appropriate to say, is it not another Node.js framework?

    Why should I bother learning it?

    Here is why?

    Grow your technical writing career in one place.

    Firstly different reasons propel a company or individual to choose a particular framework for their project.

    We will explore the benefits of using the Nest.js framework for your project over other Node.js frameworks based on our personal experience with NestJS and compare NestJS to other frameworks to help you solidify your decision.

    First, NestJS follows and improves upon the standards and structures used by the popular Front-end framework called Angular. So if you’re coming from Angular to NestJS, then you can likely get started with it in a day.

    Next, the Nest.js team focuses on building great architectural structures for enterprise applications right out of the box.

    This feature makes it easy for developers to build highly scalable and maintainable enterprise applications faster.

    If the above benefits are not enough, here are our top benefits for switching to NestJS:

    • Building scalable and maintainable enterprise-ready applications is a breeze because it uses modern technologies such as TypeScript, bullet-proof architectural patterns.
    • It also supports many popular enterprise tools right out of the box such as GraphQL, WebSockets, Kafka, RabbitMQ for building large microservice applications.
    • NestJS framework also support tools such as TypeORM, Mongoose, Logging, Validation, Caching, WebSockets, and much more right out of the box and no extra configuration is needed.

    NestJS Framework vs Other Frameworks

    Comparing the top 5 TypeScript framework with NestJS shows that NestJS is one of the top Node.js frameworks except ExpressJS and KoaJS, which has been around for quite a while and still use JavaScript.

    NestJS has more than 39,000 Github Stars and about 84,137 Github Usage as of the time of writing.

    ALSO READ  ExpressJS Tutorial: The Ultimate Guide (2022)

    It has records of 747,391 Downloads in the last one month from Jul. 25, 2021, below, and above all, it supports TypeScript as a first-class citizen with about 99.8% Typescript in its codebase.

    A picture speaks a thousand more than text. Let’s visually compare NestJS:

    nestjs typescript fraemwork
    NestJS stats from Npmtrends

    You can explore a complete comparison of Nest.js with other Node.js TypeScript frameworks for a more exquisite comparison.

    Now you have a complete overview of the Nest.js Framework, Let’s dive right into the framework itself.

    Now you have a complete overview of the Nest.js Framework, Let’s dive right into the framework itself.

    Before you dive in, I will personally recommend you check out Nest.js: The Complete Developer’s Guide course. I learned how to build full-featured backend APIs incredibly quickly with Nest, TypeORM, and Typescript, including testing and deployment!

    Want to get hired to write?

    NestJS: The Framework

    In this chapter, the tutorial will explore a little about the NestJS framework.

    We will discuss the structure of the framework and how it combines the elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming) in this tutorial.

    This tutorial will discuss the most important problem that NestJS solves in the backend web development ecosystem → Architecture.

    Finally, we will discuss how NestJS uses Angular architectural structure to solve the architectural problem of backend development to build high testable, scalable, and maintainable applications.

    You should note that the NestJS framework uses ExpressJS under the hood, and with the ultimate guide to Express, you will learn ExpressJS from beginners level to build your first real-world project with ExpressJS.

    If you’re excited as we are, let’s dive right in.

    As you may have noticed already, NestJS strongly follows the OOP, FP, and FRP architectural patterns.

    Let’s explore each of these concepts:

    What is OOP?

    Object-Oriented Programming (OOP) is a paradigm that organizes software design around data and objects rather than functions and logic.

    In OOP, everything is an object and can relate with another object to perform different functions either in a group or individually.

    What is FP?

    Functional Programming(FP) is also a programming paradigm where programs are constructed by applying and composing functions.

    When a pure function is called with arguments, it will always return the same result.

    What is FRP?

    Functional Reactive Programming (FRP) is a programming model for reactive programming (Asynchronous Dataflow Programming) using the building blocks of functional programming.

    This content will give you a clearer overview of FP, RP, and FRP to foster your understanding of the NestJS framework.

    These different paradigms and models’ combination allows developers and teams to create highly testable, scalable, loosely coupled, and easily maintainable applications and architecture the angular heavily inspires.

    Nest.js Architecture

    Nest.js uses a 3-tier architecture that separates codes into 3 main components and enables developers to create fewer spaghetti codes:

    1. Controllers
    2. Services
    3. Data Access layer
    nestjs typescript fraemwork
    Nest.js 3rd-tier layer architecture

    Controllers

    They serve as a middleman between client requests and responses. It is responsible for handling the incoming requests and returning responses to the client through HTTP protocol.

    nestjs typescript fraemwork
    Overview of Nest.js controllers

    The controller receives a specific request for the application through the routing mechanism created and processes the request.

    Nest.js uses classes and decorators to create controllers and map each class method to routes to receive a specific request.

    Here is an example of a controller using decorators:

    import { Controller, Get } from '@nestjs/common';
    
    @Controller('todos')
    export class TodosController {
      @Get()
      findAll(): string {
        return 'This action returns all todos';
      }
    }

    The @Controllers, and @Get are the decorators used to inform Nest.js that we are creating a Todos controller and the findAll method is a GET request.

    Services

    Services are part of Nest.js Providers. Providers are the fundamental of Nest.js, with the main idea of injecting it as a dependency.

    With dependency injection, relationships among various components, controllers, and other application parts are created.

    Specifically, services are part of the code block that includes only the business logic.

    For example, implementing all the database CRUD operations and methods to determine how data can be created, stored, and updated.

    Here is an example of Services used to manage an array of Todos:

    
    import { Injectable } from '@nestjs/common';
    import { Todo } from './interfaces/todo.interface';
    
    @Injectable()
    export class CatsService {
      private readonly todos: Todo[] = [];
    
      create(todo: Todo) {
        this.todos.push(todo);
      }
    
      findAll(): Todo[] {
        return this.todos;
      }
    }

    The service class uses the Injectable() decorator showing that it is a provider and it can be injected as a dependency into any other class. e.g., controllers.

    Next, we created a todos array that will contain all our todos that will be created using the create method and retrieved using the findAll method.

    Data Access Layer

    The data access layer takes care and provides logic to access data stored in persistent storage of some kind.

    It is located in the lowest level, dealing with the database and encapsulating data access details and providing a friendly access interface for the upper layer.

    Here is an example of an Entity-centric definition type:

    interface Todo {
      title: string;
      description: string;
      isDone: boolean;
    }

    The code above shows a basic type definition for our Todo data. Now this interface can be customized to represent the different database schemas and columns that our application will use.

    ALSO READ  How to implement Structured Logging in Adonisjs

    Directory Structures

    In the initial stage of every project, defining a project structure is one of the important steps as it stands as a guide throughout the entire project.

    Nest.js is important to have a project with a well-structured directory file to be much more readable, understandable, and easy to work with new and old team members to understand.

    Below is the initial project structure of Nest.js after installation:

    --src
      --app.controller.spec.ts
      --app.controller.ts
      --app.module.ts
      --app.service.ts
      --main.ts

    The app.controller.ts and app.controller.spec.ts files contain basic controller logic for a single route and the controller’s unit tests, respectively.

    Next, the app.module.ts is the root module of the application and app.service.ts is the service/data model logic of the application.

    Lastly, the main.ts is the entry file of the application which uses the core function NestFactory to create a Nest application instance.

    This simple directory structure can be expanded into a complete project by creating folders and arranging them based on its features.

    Let’s take a look at creating a simple Todo application with an authentication directory structure:

    --src
      ---auth
          --DTO
          --auth.controller.ts
          --auth.controller.spec.ts
          --auth.service.ts
          --auth.module.ts
          --auth.*.ts
      ---config
        --typeorm.config.ts
      ---todos
          --DTO
          --pipes
          --todos.controller.ts
          --todos.controller.spec.ts
          --todos.service.ts
          --todos.module.ts
          --todos.*.ts
      ---app.module.ts
      ---main.ts

    As seen above, different files and folders could be created as the project grows in size and features.

    For a holistic overview of Nest.js directory structure, check out this article Best Way to Structure Your Directory/Code (NestJS), by Prateek Kathal.

    Now that we understand the inner workings of the Nest.js framework, let’s start building our first project following the structure:

    Building with NestJS

    What better way to learn than understanding the theoretical and practical part of a technical topic.

    So far, we have learned and gained more theoretical insights.

    Let’s apply our knowledge practical to build a Todo application with Nestjs typescript framework.

    This Nest.js tutorial will demonstrate how to use Nest.js to create a simple Todo application. With this, we will explore how to set up Nest.js with TypeScript.

    Let’s dive right in:

    Setting up Nest.js

    You need to have Node.js and NPM installed on your local machi if you’re starting. To get started, download and install the latest Node.js with NPM.

    Nest.js has evolved a lot over the years, with different versions and releases coming with different changelog, but in this tutorial, we will be using the current version 8 as of the time of writing.

    To create our first project using Nest.js, we will follow the conventional way from the official documentation.

    npm i -g @nestjs/cli
    nest new nest-todo-app

    The script above installs Nest.js CLI globally and uses the nest command to create a new project with the name nest-todo-app respectively.

    Next, the script will ask you to select your favorite package manager, we will select npm and watch the command set up everything smoothly.

    Lastly, open the folder in your favorite text editor and run the following command to build and serve the project for development.

    npm run start:dev

    You can delete all the app.**.ts TypeScript files except for the app.module.ts file to keep things clean.

    Creating Controllers

    We have already discussed above that controllers in Nest.js are meant to receive incoming HTTP requests from an application frontend and return an appropriate response. 

    We can leverage the nest command to create, generate and modify Nest.js controllers, which can also help us generate some boilerplate codes.

    Type this command in your project root terminal:

    nest generate controller todo

    The command will create two files, namely todo.controller.spec.ts and todo.controller.ts.

    The first is used to write unit tests and should be ignored since it’s not the scope of this tutorial.

    The next one is a TypeScript file decorated with the @Controller annotation.

    Now, open the todo.controller.ts file and update its content with the following:

    // /nest-todo-app/src/todo/todo.controller.ts
    import {
      Controller,
      Get,
      Res,
      HttpStatus,
      Param,
      NotFoundException,
      Body,
      Put,
      Query,
      Delete,
      Post,
    } from '@nestjs/common';
    import { TodoService } from './todo.service';
    import { CreateTodoDTO } from './dto/create-todo.dto';
    @Controller('todos')
    export class TodoController {
      constructor(private todoService: TodoService) {}
    
      // Create a todo
      @Post('/')
      async create(@Res() res, @Body() createTodoDTO: CreateTodoDTO) {
        const newTodo = await this.todoService.addTodo(createTodoDTO);
        return res.status(HttpStatus.OK).json({
          message: 'Todo has been submitted successfully!',
          todo: newTodo,
        });
      }
    
      // Fetch a particular todo using ID
      @Get('/:todoID')
      async getTodo(@Res() res, @Param('todoID') todoID) {
        const todo = await this.todoService.getTodo(todoID);
        if (!todo) {
          throw new NotFoundException('Todo does not exist!');
        }
        return res.status(HttpStatus.OK).json(todo);
      }
    
      // Fetch all todos
      @Get('/')
      async getTodos(@Res() res) {
        const todos = await this.todoService.getTodos();
        return res.status(HttpStatus.OK).json(todos);
      }
    
      // Edit a particular todo using ID
      @Put('/')
      async editTodo(
        @Res() res,
        @Query('todoID') todoID,
        @Body() createTodoDTO: CreateTodoDTO,
      ) {
        const editedTodo = await this.todoService.editTodo(todoID, createTodoDTO);
        if (!editedTodo) {
          throw new NotFoundException('Todo does not exist!');
        }
        return res.status(HttpStatus.OK).json({
          message: 'Todo has been successfully updated',
          todo: editedTodo,
        });
      }
    
      // Delete a todo using ID
      @Delete('/delete')
      async deleteTodo(@Res() res, @Query('todoID') todoID) {
        const deletedTodo = await this.todoService.deleteTodo(todoID);
        if (!deletedTodo) {
          throw new NotFoundException('Todo does not exist!');
        }
        return res.status(HttpStatus.OK).json({
          message: 'Todo has been deleted!',
          todo: deletedTodo,
        });
      }
    }

    The controller implements a simple CRUD business logic for our Todo application.

    We have the create method which implements the Post method for creating a new Todo.

    Next, we have the getTodo and getTodos which implements the Get method for retrieving all and single Todo, respectively.

    ALSO READ  TypeScript vs. JavaScript: Your Go-to Guide

    Next, we have editTodo method which implements the Put method to update or edit the Todo that was already created.

    Lastly, we have the deleteTodo method which implements the Delete method and allows us to delete our Todo.

    Most importantly, every operation is performed inside the service class, which helps us separate business logic from actual data manipulation.

    Creating Services

    Services in Nest.js handle any complex business logic data manipulations for a specific purpose and return the appropriate response to the controller.

    Run the following command in your project directory to generate a new service file:

    nest generate service todo

    Open the file and add the following codes:

    // /nest-todo-app/src/todo/todo.service.ts
    
    import { Injectable } from '@nestjs/common';
    import { CreateTodoDTO } from './dto/create-todo.dto';
    
    // Creates a Todo interface to show exactly the attribute of our Todo
    interface Todo {
      readonly id: number;
      readonly title: string;
      readonly description: string;
      readonly isDone: boolean;
    }
    
    @Injectable()
    export class TodoService {
    
    // Creates a Todo array with one Todo
      private todos: Todo[] = [
        {
          id: 1,
          title: 'Test',
          description: 'This is a test Tod',
          isDone: true,
        },
      ];
    
    // Creates a new todo (Add todo to array)
      async addTodo(createTodoDTO: CreateTodoDTO): Promise<Todo> {
        this.todos.push(createTodoDTO);
    
    // return last added item
        return this.todos.at(-1);
      }
    
    // Returns a single todo with ID
      async getTodo(todoID: number): Promise<Todo> {
        const post = this.todos.find((todo) => todo.id === todoID);
        return post;
      }
    
    // Returns all todos available
      async getTodos(): Promise<Todo[]> {
        return this.todos;
      }
    
    // Deletes a todo by ID and add a new one (Update process)
      async editTodo(postID: number, createTodoDTO: CreateTodoDTO): Promise<Todo> {
        await this.deleteTodo(postID);
        this.todos.push(createTodoDTO);
    
    // return last added item
        return this.todos.at(-1);
      }
    
    // Deletes a todo from the array
      async deleteTodo(todoID: number): Promise<any> {
        const todoIndex = this.todos.findIndex((todo) => todo.id === todoID);
        return this.todos.splice(todoIndex, 1);
      }
    }

    The code above implements a simple CRUD (Create, Retrieve, Update, and Delete) operation using simple JavaScript array manipulations since we are not working with a real database.

    The comments in the code make it self-explanatory.

    Creating Modules

    In Nest.js, modules are used to organize your project into features and allow you to separate different features for easy structuring.

    The module is a class annotated with a @Module() decorator. It helps to keep the application structure organized.

    nest generate module todo

    The command above will generate a new module named todo.module.ts for the application and update the root module for it by automatically importing the newly created TodoModule.

    Inside the todo.module.ts, you can wire up everything by importing your controllers’ providers, and Nest.js will set up everything.

    Let’s take a look at how we wired up everything:

    import { Module } from '@nestjs/common';
    import { TodoController } from './todo.controller';
    import { TodoService } from './todo.service';
    @Module({
      imports: [],
      controllers: [TodoController],
      providers: [TodoService],
    })
    export class AppModule {}

    Nest, inside the TodoModule, we imported the todo.module.ts file, this should be done automatically if you use the command above.

    import { Module } from '@nestjs/common';
    import { TodoService } from './todos/todo.service';
    @Module({
      imports: [TodoService],
    })
    export class AppModule {}

    Lastly, we create our first DTO (data transfer object) to help define how data will be sent over the network and control how data will be posted from the application to the database.

    // /nest-todo-app/src/todo/dto/create-todo.dto.ts
    
    export class CreateTodoDTO {
      readonly id: number;
      readonly title: string;
      readonly description: string;
      readonly isDone: boolean;
    }

    Testing Nest.js framework

    We will test our newly developed REST API with Postman and ensure we have the right data. You can read more about Postman and install it on your local machine if you don’t already have it.

    Make sure your development server is still running or run the following command to get it up and running:

    npm run start:dev

    Open your Postman and test your backend API like below:

    Suppose you have a response as above, congrats. You can test out the remaining endpoints.

    Advanced NestJS Guide

    In the advanced NestJS Guide, what you will learn includes:

    • Database Connectivity using MongoDB and TypeORM
    • Authentication and Authorization with Nest.js
    • Real-world ticket ordering application with Nest.js
    • Write Unit Test for with Nest.js
    • Build your frontend with Nuxt.js
    • Deploy Nest.js to Heroku

    Let me know in the comments section. I will share it with you.

    Resources

    1. NestJS: The Complete Developer’s Guide is the best course I can recommend to learn and build full-featured backend APIs quickly with Nest, TypeORM, and Typescript. Includes testing and deployment!
    2. NestJS Zero to Hero – Modern TypeScript Back-end Development is another recommended course to learn NestJS. This is the course I used to get up and running with NestJS.
    3. Official Documentation
    4. Getting Started with NestJS
    5. Developing a Secure API with NestJS: Getting Started
    6. NestJS Crash Course By Brad Traversy

    Summary

    NestJS typescript framework is a backend framework used to create scalable and reliable APIs.

    It is an all-in-one typescript web framework that includes tools to handle every possible use case, from data persistence, validation, config management, testing, etc.

    Also, the Typescript web framework is officially used in Nest.js to make sure writing clean and correct codes are achieved.

    Now, it’s your turn to practice everything you have learned from this Nest.js tutorial until you master them by building real-world projects.

    Let me know what you will be making. If none, comment “Nest.js is Great,” we may connect from there.

    Ready to ditch Google Drive? Try Contentre.

    Start Learning Backend Dev. Now

    Stop waiting and start learning! Get my 10 tips on teaching yourself backend development.

    Don't worry. I'll never, ever spam you!

    Sharing is caring :)

    Coding is not enough
    Learning for all. Savings for you. Courses from $11.99

    Comments