Creating your first NestJS application

In this article, I’m going to walk you through developing a simple todo rest application in NestJS and give you an overview of this framework.

Photo by Sereja Ris on Unsplash

What’s NestJS?

NestJS is a framework for a fast development of backend applications whose structure, inspired from Angular, makes it perfect for the realization of projects with MEAN stack.

When to use NestJS?

Nest is most suitable for developing applications that manage a huge quantity of requests with a tiny amount of data processed on the server side and prompt response time (e-commerce, live chats, etc..).

Why use NestJS?

The benefits of using NestJS are innumerable. The most important (imho) to highlight are:

  • Type checking: with Typescript we exploit all the power of javascript without running into type problems.
  • Modular: through the division into modules we can isolate our components based on the domain boundary.
  • Dependency Injection: thanks to the DI container we are able to write decoupled and testable code.
  • Adapters: Nest integrates all the most used and community tested javascript / typescript libraries and provides all the tools developers need to contribute to the collection.
  • Angular Like: the familiar structure allows us to easily switch from frontend to backend without having to change the development approach every time.
  • CLI: we can develop our functionality without having to worry about the initial boilerplate.

Let’s start writing code

  • retrieve the list of all todos
  • retrieve a single todo
  • insert a todo
  • edit a todo
  • delete a todo

therefore of the following APIs:

  • [GET] todos
  • [GET] todos/{id}
  • [POST] todos
  • [PUT] todos/{id}
  • [DELETE] todos/{id}
Ehm 😅

Setting up our project with two simple commands in terminal:

npm i -g @nestjs/cli
nest new TodoBackend

Run $ npm run start in todo-backend folder to make sure everything is okay!

NestJS bootstrap logs

Modules are the mechanism that allows us to separate our components based on a domain they belong to and, in practice, to instruct the DI container about their interactions in the bootstrap phase.

The main module with which the bootstrap is performed is called root module and, in applications generated via CLI, we find it in the src folder under the AppModule name.

Our application, being very small and with a single functionality, could directly exploit the root module to manage its dependencies. There are at least two good reasons we won’t be doing this in this guide:

  • It’s not a typical case and consequently difficult to apply in a real context.
  • We would not be decoupled, thus losing the maintainability and portability of our code.

We create our module via CLI:

nest generate module todo

When it’s generated, the CLI will also take care of updating the AppModule by importing TodoModule as a feature module 🎉

An entity is a class that maps a table (or collection) of our database (very pragmatic definition).

We create our entity through CLI:

nest generate class todo/entities/Todo --no-spec

Now that we have our entity we just have to persist it through an ORM!

For this guide I have decided to use Typeorm and setting up a basic connection to an sqlite database.

First we install the dependencies:

npm i @nestjs/typeorm typeorm sqlite3

We modify AppModule by importing TypeOrmModule with the static method forRoot, inserting the configurations we need:

Let’s add TypeOrmModule also on TodoModule, this time using the forFeature method, specifying Todo as the entity to manage:

Now that we’ve configured Typeorm we can finally update our Todo entity with all the necessary annotations:

You can read further informations about Typeorm and its annotations by consulting the link attached at the beginning of the step. For TypeOrmModule forRoot and forFeature methods, you can consult the database section in the official NestJS documentation:

To avoid exposing our entities outside our business logic layer, we define a set of classes that will be used to manage the communication in and out of our services: the DTO (Data Transfer Objects).

The service is the “package” where we are going to encapsulate our business logic, exposing a set of ready-to-use features.

Let’s define the objects that will populate our service layer:

nest generate service todo/services/todo

In the created service, we implement the findAll, findOne, add, edit and delete methods which, through the DTOs, will be consumed by our controller.

To decouple the conversion logic from Entity to DTO (and vice versa) from the business logic, let’s create a TodoMapperService:

nest generate service todo/services/TodoMapper

Now let’s implement our TodoService: we inject, through Dependency Injection, the Todo Repository provided by Typeorm and our TodoMapperService:

Here we are at the last layer of our climb to the NestJS stack! ⛰

To create our controller we will use our very useful CLI for the last time with this command:

nest generate controller todo/controllers/todo

Let’s implement the methods that will mirror the rest calls we listed at the beginning of the article, decorate them with routing annotations and hook them to the TodoService methods:

WARNING: DTO serialization is not active unless you decorate your controller method with ClassSerializerInterceptor

public add(@Body() todo: AddTodoDto): Promise<TodoDto> {

In the next step we will deepen this topic by developing a solution that allows us to centralize this interceptor 😉

Our DTOs are ready to travel as fast as Formula 1 cars under the http protocol but one last piece is missing: the validation of its data.

To handle the validation of our fields, NestJS provides a validation pipe that takes advantage of the class-transformer and class-validator libraries. To be able to use it however, we need to install its dependencies in the project:

npm i class-transformer class-validator

Let’s add the ValidationPipe to the global pipes:

And now let’s decorate our DTOs:

WARNING: Once our application has been compiled, all the DTOs we have defined so far will be converted into javascript objects, this means that no type check will be performed on the values of its fields!

So will our validators only work as long as they are passed the right type values? NO.

The class-validator library also has a set of validators specifically designed to type check our fields at runtime:

It’s time to run our application! 🎉

To execute it normally, just run the command:

npm run start

If we need to debug our code, we will have to run the command:

npm run start:debug

After developing our backend, we will most likely want to develop a frontend application and try to consume our todo-backend, here the CORS comes into play:

Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. […] For security reasons, browsers restrict cross-origin HTTP requests initiated from scripts. For example, XmlHttpRequest and the Fetch API follow the same-origin policy.

To enable CORS just edit main.ts again by invoking the enableCors() method with all the configuration parameters we need. For simplicity, we will enable everything! (Freedom! 🤟)

Tests are absolutely necessary when you want to build a maintainable application: they prevent us from the most common development errors and possible regressions due to the modification of an existing functionality.

When we generate a new component via CLI, its test file is also automatically generated. Let’s try to make one:

For test development, Nest uses Jest under the hood

for more information see the NestJS documentation

You can find the sources of this article on my Github repository, feel free to put a ⭐️ 😁


By creating the application described in this article, I was able to see firsthand how fast and powerful this framework is: it allows you to be extremely fast and flexible without having to give up absolutely anything. NestJS passes exams with top votes and can deservedly occupy its place in the top list of frameworks for web development.

If you enjoyed this guide, don’t forget to 👏 and share it with all the people who might benefit from it 😃

So long, and thanks for all the fish 🐬



Fullstack Developer | Based in Florence | |

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store