Double click to toggle Read Mode.

NestJS Course

Github Link

Table of Content

  1. Nest from Scratch
  2. With Nest CLI
  3. Validating data with ValidationPipe

Nest from Scratch

Initialize project and install dependencies

LibraryDescription
@nestjs/commonContains vast majority of functions, classes, etc, that we need from Nest
@nestjs/coreThe core runtime of NestJS that powers dependency injection, module loading, and lifecycle management
@nestjs/platform-expressLets Nest use Express JS for handling HTTP requests
reflect-metadataHelps make decorators work. Tons more on this in just a minute!
typescriptWe write Nest apps with Typescript.

Initialize typescript - (tsconfig.json)

{ "compilerOptions": { "module": "commonjs", "target": "es2017", "experimentalDecorators": true, "emitDecoratorMetadata": true } }
SettingDescription
"experimentalDecorators": trueEnables the use of decorators (@Something) in TypeScript. Without this, NestJS decorators (like @Controller()) would throw errors.
"emitDecoratorMetadata": trueWorks together with the reflect-metadata library. Emits extra type information about classes and methods at runtime, which NestJS uses for dependency injection.

Common pattern in server

flowchart LR
    A[Request]
    G[Response]
    subgraph Server
        direction LR
        B[**Pipe**<br/><br/>Validate data<br/>contained in<br/>the request]
        B --> C[**Guard**<br/><br/>Make sure<br/>the user is<br/>authenticated]
        C --> D[**Controller**<br/><br/>Route the<br/>request to a<br/>particular<br/>function]
        D --> E[**Service**<br/><br/>Run some<br/>business logic]
        E --> F[**Repository**<br/><br/>Access a<br/>database]
    end

    A --> Server
    direction RL
    Server --> G

    %% Define style classes
    classDef bigText font-size:30px;

    %% Apply them
    class A,B,C,D,E,F,G bigText

NestJS provides More

PartDescription
PipesValidates incoming data
GuardsHandles authentication
ControllersHandles incoming requests
ServicesHandles data access and business logic
RepositoriesHandles data stored in a DB
ModulesGroups together code
FiltersHandles errors that occur during request handling
InterceptorsAdds extra logic to incoming requests or outgoing responses

We need at least module and controller

Create (src/main.ts)

import { Controller, Module, Get } from "@nestjs/common"; import { NestFactory } from "@nestjs/core"; @Controller() class AppController { @Get() getRootRoute() { return "hi there!"; } } @Module({ controllers: [AppController], }) class AppModule {} async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); } bootstrap();

Run

npx ts-node-dev src\main.ts

Check at localhost:3000



Refactoring

File Structure

Conventions

Create app.controller.ts

import { Controller, Get } from "@nestjs/common"; @Controller() export class AppController { @Get() getRootRoute() { return "hi there!"; } }

Create app.module.ts

import { Module } from "@nestjs/common"; import { AppController } from "./app.controller"; @Module({ controllers: [AppController], }) export class AppModule {}

Update app.controller.ts

import { NestFactory } from "@nestjs/core"; import { AppModule } from "./app.module"; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); } bootstrap();

Adding more Routes

Update app.controller.ts

import { Controller, Get } from "@nestjs/common"; @Controller("/app") export class AppController { @Get("/hi") getRootRoute() { return "hi there!"; } @Get("/bye") getByeThere() { return "bye there!"; } }



With Nest CLI

Install nest cli

npm i -g @nestjs/cli

Create nest project (message)

nest new project_name

Run the project

npm run start:dev

Delete everything in src folder except main

Generate messages module

nest generate module messages

Use message module in main (Remove app module)

import { NestFactory } from "@nestjs/core"; import { MessagesModule } from "./messages/messages.module"; async function bootstrap() { const app = await NestFactory.create(MessagesModule); await app.listen(3000); } bootstrap();

Generate Controller inside messages folder

nest generate controller messages/messages --flat

Update src/messages/messages.controller.ts

import { Controller, Get, Post } from "@nestjs/common"; @Controller("messages") export class MessagesController { @Get() listMessages() {} @Post() createMessage() {} @Get("/:id") getMessage() {} }

Test using Postman or Thunder Client (vscode extension) for success status code

Access Body and Params

import { Controller, Get, Post, Body, Param } from "@nestjs/common"; @Controller("messages") export class MessagesController { @Get() listMessages() {} @Post() createMessage(@Body() body: any) { console.log(body); } @Get("/:id") getMessage(@Param("id") id: string) { console.log(id); } }

Test for console log




Validating data with ValidationPipe

npm install class-validator class-transformer
import { NestFactory } from '@nestjs/core'; + import { ValidationPipe } from '@nestjs/common'; import { MessagesModule } from './messages/messages.module'; async function bootstrap() { const app = await NestFactory.create(MessagesModule); + app.useGlobalPipes(new ValidationPipe()); await app.listen(3000); } bootstrap();

Create class describing properties of request body

export class CreateMessageDto { content: string; }

Add validation rules

+ import { IsString } from 'class-validator'; export class CreateMessageDto { + @IsString() content: string; }

Apply Validation in Controller route handler

How just adding dto type works?

When ts compiles to js. Type information is lost but Because of emitDecoratorMetadata in tsconfig, some of type information is also converted into javascript

import { Controller, Get, Post, Body, Param } from '@nestjs/common'; + import { CreateMessageDto } from './dtos/create-message.dto'; @Controller('messages') export class MessagesController { @Get() listMessages() {} @Post() + createMessage(@Body() body: CreateMessageDto) { console.log(body); } @Get('/:id') getMessage(@Param('id') id: string) { console.log(id); } }

What is happening