If you are interested in reading this article in Spanish, check out my blog:
The Developer's Dungeon
Hey guys, how you been? me? I have been working a lot on a new project I am building with the help of a friend, I will not discuss the details here but you will probably hear me talk about it very soon. Today I want to speak about one of the technology selections I made for building this project.
I wanted to build an API, using node, using TypeScript. I have heard a lot of great things from this backend framework called Nest.js but I hadn't tried it myself. Now after a week of coding the API, having several endpoints, authenticating, connecting to a database, and stuff I will give you my honest review. But let's start from the beginning.
What is Nest.js?
From the documentation itself we get this answer:
A progressive Node.js framework for building efficient, reliable, and scalable server-side applications.
That doesn't say much right? well in my own words, Nest.js is a Node.js framework built on top of express.js and TypeScript that comes with a strong opinion on how API's should be built. Since it is very opinionated it provides a structure, a CLI, and an almost infinite amount of tools that let you create professional APIs very very fast.
I guess it would be like Django for Python or asp.net Core for C#.
What is it like?
Well, as with most API frameworks, Nest.js defines endpoints through an entity called Controller
.
import { Controller, Get } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll(): string {
return 'This action returns all cats';
}
@Get(":id")
findOne(@Param('id') id:string): string {
return 'This action returns one cat';
}
}
For me, coming from C#, to see this in the JavaScript is just a pleasure. But I guess it can be daunting for you noders out there, so let me explain all the goodies that are happening in the previous example.
This Controller
will create 2 endpoints in the routes {url}/cats
and {url}/cats/{id}
, the id in the URL of the second endpoint will be automatically mapped to the id parameter in the method.
These types of tags @Get()
are called decorators and there are a bunch of them, you can use them for defining the HTTP method, for getting properties, for defining authentication, basically whatever you feel like.
But where do you write your business logic? you might ask. Well Nest.js got you covered, for that you will use an entity called Service
import { Injectable } from '@nestjs/common';
import { Cat } from './interfaces/cat.interface';
@Injectable()
export class CatsService {
private readonly cats: Cat[] = [];
create(cat: Cat) {
this.cats.push(cat);
}
findAll(): Cat[] {
return this.cats;
}
}
Nothing too weird here, except, what is that @Injectable
decorator doing?. Nest.js comes with Dependency Injection
by default, this decorator defines which dependencies can be injected into other components through their constructors.
This seems like is gonna generate a lot of code, is there an easy way to manage dependencies? yes, there is. You can pack functionality together by using Modules, they are like Node Modules but in Nest.js you can hold controllers, services, and more inside one Module that represent a feature, then inject that entire module into others to be used there.
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
@Module({
controllers: [CatsController],
providers: [CatsService],
})
export class CatsModule {}
I don't see any mention of how to contact a database, is there something for that?. Didn't I tell you that Nest.js is pretty opinionated? as such, it comes with a way of working with databases. Enters TypeORM.
Instead of doing SQL queries manually, we use an Object Relational Model, for working with the database, we define database entities that later will be used for creating the tables on the application startup and use automatic Repositories
created based on our database model.
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Cat {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 500 })
name: string;
@Column('text')
color: string;
}
Seems super complicated, who is it for?
I would lie if I say that everyone who starts messing with Nest.js is going to be productive immediately.
- Nest.js follows a pattern that is very Object-Oriented, which is not something we see very often in the JavaScript world.
- If you only know dynamically typed languages is gonna be hard doing a switch because of TypeScript.
On the other hand, if you come from a language like C#, then TypeScript is gonna feel right at home(they were actually designed by the same guy). On top of that, you probably used a framework like asp.net Core so you know exactly what a Controller
is, you probably created a layered architecture and used the word Service
to define your business logic even before seeing a single line of Nest.js code.
But, I have never done any backend, can I take Nest.js as my first project? It depends.
Nest.js is gonna be easier for you if you come from Angular instead of React.
The entire Module, Dependency Injection, Decorator architectural patterns that Nest.js uses is heavily inspired in Angular, they are like cousins, and if you come from Angular you will already know TypeScript so picking up Nest.js will be a no brainer.
Conclusion
You probably know that I gonna say I really like Nest.js, well yeah, it seems like a great framework to create reliable node.js APIs. It provides tons of functionality out the box, and if you wanna do something special, their documentation is just outstanding. If you come from one of the backgrounds I mentioned previously or you just want to learn something new I would definitely recommend you to give Nest.js a try 🤞.
As always, if you liked this post go ahead and share it, have you tried Nest.js? Do you want to know something specific? let me know below in the comments 😄
Top comments (7)
I love it as well. Decent choice for Angular-focused front-end developers that would like to dive into back-end development deeper (for side projects or even something more sophisticated). Good SoC, easy swagger generation, possibility to easily share data models with Angular front end. All in all, highly recommended 👍
It gets even better if used in a Monorepo with Angular and NX
Do I need to be an expert at TS to work with NestJS
Sorry for the delay in my response, I have been out of the writing world for some time. No, you don't need to. I am not an expert myself and I work with nest.js now.
I would say no, basic knowledge is enough
Totally agree with your conclusion. Moving from raw express with TypeScript to NestJS has been a breath of fresh air, especially since I come from an object-oriented background. I didn't know that having good support for following important architectural principles and using mechanisms like dependency injection was even a possibility in Node until discovering NestJS.
On the integration front, it helped me quickly implement GraphQL APIs and also to set up Apollo Federation down the road quite easily. Very good third party support for lots of the tech found in many modern stacks today.
I also agree that the documentation is outstanding, world class compared to most open source projects.
Also, yeah it's probably overkill for small projects that aren't likely to grow much. But since I know it, I would use it for even small proofs of concept.
Nice article, I've been using nestjs for 3 weeks, i had background from react,
I love how it is organized and well documented.