Building a RESTful API with NestJS and MongoDB (Mongoose)

Introduction

We will learn how to implement a RESTful API for a simple todo application using NestJS framework. But what is NestJS?

“A progressive Node.js framework for building efficient, reliable and scalable server-side applications.”

You can read more about NestJS here.

In this article, it assumes you have at least the basic understanding of TypeScript and even better with NodeJS and ExpressJS. However if you aren’t familiar with these requirements, I will list down you what I recommend you to watch to learn from:
- TypeScript by Fireship
- NodeJS by Fireship
- ExpressJS by Traversy Media

I also recommend you to subscribe on those YouTube channels as they produce high quality content and it’s for free! I have other favorite YouTube channels as well but I will write it in another article.

And if you are a frontend developer and have been using Angular for awhile, then this should be very familiar to you since NestJS is very similar with how Angular code is structured! Dependency injections, modules, generate code using CLI, and so much more!

Installation

This installation guide will be based on for Linux since I am using WSL2 on Windows and it is my preference and find it more convenient. I believe installation process is very similar but in case for other platforms I suggest you to consult the documentation that can be found [here](https://docs.nestjs.com/first-steps)

Installing Nest CLI

Open up your terminal and execute this command to install Nest CLI

To test it out if it has been successfully installed just execute the command below and that should tell you the current version installed for Nest CLI

Create a new Nest project

Navigate to your projects directory or in any directory whichever you prefer and run this command below to install you a new project

If it asks you which package manager to select from, just choose anything you prefer but in this article I will select NPM.

And now wait for the entire CLI to scaffold the new starter project for you.

Open the project in your IDE

Once that is done installing, open it on your preferred code editor. In my case I will open it with VSCode (Visual Studio Code), so I will execute in the terminal with this command

Then that should open up your IDE.

Creating “Todo” feature

We can easily generate code for the Module class, Service class, Controller class by using the powerful CLI.

One thing to take note is that when creating a new feature, you should start by generating a module class for the particular feature. So for instance is being generated first.

So let us generate them right on!

This should create a folder called “todo” and it will also add the under the array in and the in the array.

Creating a Todo model/schema

Before we proceed to writing the code for handling data and exposing it to the REST API we first create a data model for Todo. So let us create a schema using Mongoose package, so let’s install it

Right after installation make sure to add `MongooseModule` into the imports array. We’ll want to import this under `AppModule` so we let the application know where the MongoDB is coming from.

However if you don’t have MongoDB installed in your system you can use this as reference if you are using Linux based system

After adding in we can then proceed to defining our Todo schema, so head on over to “todo” directory as this feature directory has been generated by the CLI, so under this directory create a folder named “schemas” and it’s where the Todo schema resides

Or you can do so by using this terminal commands

Then let us define our Todo schema

Then let’s create a DTO (Data Object Model) for creating and updated a Todo. But first I want to create a base class DTO

Then we define the class and properties

Then let us create a DTO for Create and Update that will extend this so for all properties defined under will carry over the new classes and so we won’t have to rewrite all of these properties. So in a sense we aren’t writing any boilerplate code in this case.

Then we can define it

We added field on the so we’ll allow this field to update with that particular field we specified.

After defining out model make sure to import this under so this will be recognized as a in the codebase.

Injecting the Model in TodoService

Under class , is here we want to define the logic for handling data. So in the constructor we will then inject the Model as our dependency for this class. The model I am referring to is what we just added into the array of the

In the constructor we use annotation and we pass in the name of the model and we set it as a private property and gave it a type of where we also pass a generic type of that we defined from the Todo model from . This will give us all the methods from Mongoose for querying, altering ang creating data for MongoDB which is very convenient as it gives us the auto-completion.

You may also notice that it has the annotation which is very similar to Angular’s service classes. This annotation creates the meta data and this makes the class recognized in the service locator other classes will be available to use this class as their dependency.

Defining CRUD functionalities

Now let us proceed with defining the usual CRUD methods. We will have the following methods to write up the implementation details, , , , , and .

Defining methods and route endpoints in TodoController

It is very easy to define routes in our Controller class and all thanks to TypeScript for these annotations just made everything a breeze! We have to inject the as our dependency for this class and then define all methods with its corresponding annotation as this will handle which HTTP method it will be used to access the functionality.

We will use the following names in the where is for querying all Todo, to query a single Todo, is to add a Todo in DB, to update an existing Todo based on given ID, and lastly to delete a Todo.

Testing it with a REST client

You can use any REST client of your choice, but for me I prefer Insomnia. Once you have your REST client opened by now we can proceed to testing the REST API we created so we can expect to add a todo, update a todo, delete a todo, read a todo.

First let’s make a GET request to endpoint.

It just returned an empty array, and it only makes sense since we did not create any todo. So let’s create one!

Make this as the request payload then make a POST request to the same endpoint and that it should return as the new document from MongoDB with an field since that is auto generated for us.

You can create more todos, but for now we can check again with the same endpoint but using `GET` method.

Now it returns as a array with our recently created todo.

Now let’s update this todo, to change its title. First copy field from the response. Now using this ID, let’s create a PUT request with the same payload but now we add the field

As you can see we have filled up the field. On the first request that you make which returns 200 response but the response data is still the same, don’t worry because behind the scenes the document was really updated. You can proceed to check again by GET request method to see the changes, alternative way is to update the document again. So double the PUT request we are making right now and you should see the changes.

Now we want to delete this todo, then let’s use the DELETE method in this case using the same endpoint but different HTTP method. It will return us the document deleted.

And that is all we have for now.

Conclusion

When you want to create a quick REST API with NodeJS and you also love TypeScript, then NestJS is the way to go! Not only this is good for “quick” implementation for REST APIs but NestJS is also great for huge projects since the framework itself encourages the developer to use Domain Driven Design.

Hope you enjoyed this tutorial, be sure to hit thumbs up or upvote if you liked it. Cheers!

Full source code can be found from the repository

Software Engineer & Full-Stack Developer

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