Backend Development with NestJs Introduction Tutorial

lsmod
4 min readOct 8, 2019

If you are looking for a new back-end framework you should have a look at NestJs.

NestJs or simply Nest is a contender of express with the particularity of using typescript. Its architecture proudly takes its inspiration from angular (as you can read in the README.md of the starting kit Github repository). With modules, controllers, providers/services and first-class dependencies injection.

import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module';
import { User } from './users/entities/user.entity';
@Module({
imports: [DatabaseModule.forRoot([User])],
exports: [DatabaseModule],
})
export class ApplicationModule {}

Just with that example you can all ready tell it look a lot like an angular app! With @Module instead of @NgModule.

On the official Github repo you can read:

Nest aims to provide an application architecture out of the box which allows for effortless creation of highly testable, scalable, loosely coupled and easily maintainable applications.

I think it really resumes it. I don’t really know about “the loosely” part but with Nest you really get an application framework. To me, that alone makes it a real contender of Express. By the way, Nest uses Express under the hood but you can configure it to use Fastify instead.

Nest will force you to organize your project and everything will fall in place:

  • controllers to handle the routes
  • providers to fetch data from various places (database, web API)
  • validation within DTO classes
  • authentication verification with guards
  • error handling through Pipes
  • unit tests with .specs.ts files
  • End-to-End tests with .e2e-spec.ts files

All that is based on solid modules like typeorm, Jest, supertest, multer, express, class-validator, sequelize, mongoose. All that with added Typescript support.

Validation DTO / Decorator :

Besides having an organized architecture, I think having types will help your API to be more reliable.

Let’s say you are using express, you created your routes and access to your database. What is left to do ?
Data validation! There is the real piece of work.
You don’t want your API to accept invalid data. You will also want proper error messages, some tests, and documentation/specification.

Tests are integrated and encouraged as I said before.
Documentation can easily be done with Nest’s module dedicated to swagger specification.
Typescript will help you a lot with validation (especially with DTO classes).

Nest encourages you to create validations classes that will ensure that data received through various endpoints are correctly formated/validated. Let me show you an example :

export class CreateUserDto {
@IsString()
@IsOptional()
readonly lastName: string;
@IsString()
@IsOptional()
readonly firstName: string;
@IsPhoneNumber()
readonly phoneNumber: string;
@IsEmail()
readonly email: string;
}

CreateUserDto class above is made to receive a POST request to create a new user. Annotations like @IsEMail are used to ensure posted data are valid.

Know let see how a route handling validation looks like:

@Post()
async create(@Body() createUserDto: CreateUserDto): Promise<User> {
return await this.service.createUser(createUserDto);
}

And that’s all it takes to be sure we will only accept correctly formatted user data (with valid a email, phone number, and all the required fields). @Body() createUserDto: CreateUserDto to specify or data type/formatting. Posting an incomplete user will result in a 400 error with an error message about the missing/incorrect field.

Nice isn’t it ?

NestJs database entities :

What about fetching data from our database ?
To do so we have to create two things:

  • a service (will be used by the controller)
  • an entity to describe the data we want to fetch/create/update

Here’s what our entity may look like:

export class UserEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
lastName: string;
@Column()
firstName: string;
@Column()
phoneNumber: string;
@Column(unique: true })
email: string;
}

Now our service:

@Injectable()
export class UserService {
constructor(
@InjectRepository(UserEntity)
private userRepository: Repository<UserEntity>
) { }
async createUser(user: User): Promise<User> {
return await this.userRepository.save(user);
}
}

That’s all it take to be able to save your user to our database. Nest usage of typeorm save us the writing of insert, update, select queries. Even better it supports NoSQL databases like mongoDB.

Hmmm, actually I lie. It’s not all it takes… We also have to define an interface. We received data formated through createUserDto class and we wish to insert it using a format matching our UserEntity. That's why we used the User interface :

export class User {
id?: number;
firstName: string;
lastName: string;
password: string;
phoneNumber: string;
email: String;
}

Conclusion :

I hope this short introduction tutorial will make you want to learn more about Nest. I personally believe it has a bright future in Node.js ecosystem.
It’s also not the only framework to have taken the road of typescript. Loopback is also coming this way with its version 4, but it’s a subject for another post…

Please leave a comment if you would like to read more post about Nest from me.

--

--

lsmod

Self-taught programmer; passionate about Rust & Blockchains