Not so different from any other ordinary type of project, multi-tenancy is a software architecture that has been in place for quite a while, and as with any other approach, there are pros and cons. In this article, I plan to walk you through a simple solution I implemented to tackle basic architecture inside the universe of the NestJS framework with TypeORM.
Context
I've been studying and trying new approaches whenever something pops up and I wonder how to do that technically, or when I found something cool! I've written a few articles with this idea in mind, and this one is no different! I was talking to my brother the other day and he is planning to migrate a project that runs with PHP to node and he asked me if I knew an example of multi-tenancy with NestJS. Despite being in the technology for a while, I worked on something with C++ in the past but not with Node or NestJS. In the end, it wasn't a problem, I took it as my new study subject and tried it!
The final code is available on the link below on GitHub
You can find more details about the concept online. (
in case you want to check it out.
, which is "A continuation-local storage module compatible with NestJS' dependency injection based on AsyncLocalStorage". You also can use the node implementation with async_hooks if you want. The module gets the tenant-id from the request and adds it to the local storage which makes the info available through the request lifecycle.
Continuation-local storage allows to store state and propagate it throughout callbacks and promise chains. It allows storing data throughout the lifetime of a web request or any other asynchronous duration. It is similar to thread-local storage in other languages.
With the DatabaseModule module added to your Module, you can import the Database service and call
this.userRepository = this.databaseService.getDataSource().getRepository(User);
This line will return an instance of the correct database according to the tenant-id from the header and the User repository to use as needed.
And that's all my friends! We did it!!!
Bonus: Generating migrations
This project is set up in a way that you can use the TypeORM generate command! After making any change in the entities, you can run yarn typeorm:generate, and it will generate the migrations for you. You won't need to run with another command, because the application will run for you once it starts because of the migrationsRun: true
In the readme file, you can find a section about how to run the application
https://github.com/henriqueweiand/nestjs-typeorm-multi-tenancy/blob/main/README.md
Conclusion
In this article, we explored a practical implementation of multi-tenancy using NestJS and TypeORM. The solution demonstrates how to handle multiple databases for different customers while maintaining a clean and organized codebase.
The key achievements of this implementation include:
- Successfully setting up a NestJS project with multiple database support
- Creating a system that manages database connections for each customer
- Implementing database migrations and proper connection handling
While this implementation provides a solid foundation, there are opportunities for improvement, such as:
- Adding real-time database verification without requiring app restart
- Implementing a caching layer for better connection management across scaled applications
Overall, this approach offers a practical solution for implementing multi-tenancy in NestJS applications while maintaining flexibility and scalability.
SOCIAL SHARE CARD GENERATOR