API with NestJS #62. Introduction to MikroORM with PostgreSQL

JavaScript NestJS

This entry is part 62 of 121 in the API with NestJS

So far, in this series, we’ve used a few different solutions for managing databases. To work with MongoDB, we’ve used Mongoose. To manage a PostgreSQL database, we’ve utilized TypeORM and Prisma. This article looks into another Object-relational mapping (ORM) library called MikroORM. By having a broad perspective on what’s available, we can choose the library that fits our needs the most.

You can find all of the code from this article in this repository.

Setting up MikroORM and PostgreSQL

The most straightforward way to use PostgreSQL in our project is to use Docker. In the second part of this series, we set up PostgreSQL and TypeORM. Therefore, we can use the same  file we created back then.

docker-compose.yml

Also, we need to create a file that contains the variables our docker container needs.

docker.env

Connecting to the database

To be able to connect to the database, we need to establish a set of environment variables our NestJS application will use.

app.module.ts

We also need to create a file that contains the values for the variables we’ve defined above.

.env

In this series, we use PostgreSQL. Because of that, we need the  package, among others.

With all of the above, we can create our that establishes a connection to the database.

DatabaseModule.ts

Don’t forget to import the in the .

Defining a basic entity

Thanks to using the property, MikroORM loads the entities we define. First, let’s create an elementary entity for a post. To do that, we can use a set of decorators provided by the package.

post.entity.ts

For MikroORM to detect the above entity, we need to register it in the module.

posts.module.ts

Interacting with the entities

The above file mentions the and . Let’s start by creating the latter.

posts.service.ts

MikroORM uses a widespread repository pattern. We can easily create, modify, fetch, and delete entities with it.

Getting all entities

To get a whole list of entities from our database, we can use the method.

Getting an entity with a given id

Besides the above, we also have the method. If we provide it with the correct argument, we can fetch a post with a given id.

We could also use the above method to find a post with a particular title, for example.

We use the , which is a custom exception.

postNotFound.exception.ts

MikroORM uses the Identity Map pattern to track the data. Whenever we fetch an entity from the database, MikroORM keeps its reference. This allows for a bunch of optimizations. For example, fetching a post with the same id twice returns the same instance and runs only one SELECT query.

Creating an entity

MikroORM handles transactions automatically and aims to batch as many of our queries as possible. Because of that, we need to tell MikroORM to persist changes to the database explicitly.

If you want to know more about transactions, check out API with NestJS #15. Defining transactions with PostgreSQL and TypeORM

We call the method to mark the entity as something we want to synchronize with the database.

When we later call the method, MikroORM stores all of the changes we’ve marked with the method to the database.

We can combine both of the above actions by using the method.

Editing an entity

To modify an entity, we can get it from the database and modify it. Then, when we flush all of the changes, MikroORM persists them in the database.

We can simplify the above code by using the function provided by MikroORM. It allows us to use various helpers, such as .

By default, does not merge objects recursively. To achieve that, we would need to use instead.

Please notice that using allows us to implement the PATCH method, not PUT. The above is because it won’t remove properties if we don’t explicitly set them as .

Removing an entity

We need to mark the entity for removal and flush the changes to remove an entity.

We can simplify the above function by using the method.

Putting all of the features together

When we incorporate all of the above features into our service, it looks like that:

posts.service.ts

We also need a controller that uses our service.

posts.controller.ts

Synchronizing our entities schema with the database

Doing all of the above does not create a table in our database. To achieve that, we need to create a migration. We will need the MikroORM CLI and a dedicated package.

The CLI needs a separate configuration. To provide it, let’s add the following to the package.json first:

package.json

We also need to create the file in the directory.

mikro-orm.config.ts

Because the is not a part of a NestJS application, we initialize the manually.

When we run , MikroORM checks the difference between our entity schema definitions and the state of the database. If there is a difference, it generates migration files.

Migration20220522201347.ts

When we run , MikroORM performs the above migrations to bring our database to the latest state.

MikroORM keeps track of all of the migrations in the table.

Summary

In this article, we’ve gone through using MikroORM with PostgreSQL and NestJS. It included learning how MikroORM works by implementing all of the Create, Read, Update and Delete (CRUD) operations. To do that, we had to understand how MikroORM works under the hood and how to synchronize changes with the database. We also learned the basics of migrations and created them using the MikroORM CLI.

Series Navigation<< API with NestJS #61. Dealing with circular dependenciesAPI with NestJS #63. Relationships with PostgreSQL and MikroORM >>
Subscribe
Notify of
guest
3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
user007
user007
2 years ago

Very good article! Thank you!

Ayee
Ayee
2 years ago

What about error/exception handling?

Durgadas
Durgadas
2 years ago

Thanks for the article. How do we specify ‘schema’ to be used within the MikroOrm config ? TypeOrm used to support field called ‘schema’.