Introduction
In today's rapidly evolving application development landscape, efficient and scalable setup is essential for building robust applications. At CyberMind Works, we leverage NestJS and Mikro-ORM to create scalable, maintainable, and high-performance applications. This blog post will guide you through the steps to set up NestJS with Mikro-ORM as the ORM of choice.
Why Choose NestJS?
NestJS offers a robust architecture that incorporates elements from Object-Oriented Programming (OOP), Functional Programming (FP), and Functional Reactive Programming (FRP). Here are key reasons why NestJS is an excellent choice:
- TypeScript Support: Ensures type safety and scalability.
- Modular Architecture: Promotes code reusability and maintainability.
- Dependency Injection: Simplifies testing and managing complex dependencies.
- Seamless Integration: Works well with other libraries such as TypeORM and Mongoose.
Why We Chose Mikro-ORM?
Mikro-ORM is a TypeScript ORM for Node.js based on Data Mapper, Unit of Work, and Identity Map patterns. It supports various SQL and NoSQL databases and provides advanced features like migrations, seeding, and caching. Mikro-ORM's flexibility, TypeScript support, and active development community make it an excellent choice for our applications.
Project Setup: Setting Up NestJS
Prerequisites
Ensure you have the following installed on your machine:
- Node.js (version 12 or later)
- npm (Node Package Manager)
Installation
- Install NestJS CLI: The CLI is a powerful tool for initializing, developing, and maintaining NestJS applications.
npm install -g @nestjs/cli
1. Create a New Project: Use the CLI to create a new project.
nest new project-name
2. Navigate to Project Directory:
cd project-name
Project Structure
NestJS provides a well-organized project structure out of the box:
src/
: Contains the main application code.app.module.ts
: The root module.main.ts
: The entry point.test/
: Contains unit and end-to-end tests.
Adding Mikro-ORM
Next, we will add Mikro-ORM to our NestJS project.
1. Install Mikro-ORM and dependencies:
npm install @mikro-orm/core @mikro-orm/migrations @mikro-orm/nestjs
# For PostgreSQL, use:
npm install @mikro-orm/postgresql pg
2. Install TypeScript and other necessary tools:
npm install typescript ts-node @types/node --save-dev
Configuring Mikro-ORM
To configure Mikro-ORM, we need to set up the `mikro-orm.config.ts` file and configure it in our NestJS project.
Create `mikro-orm.config.ts` in the project root:
import { Logger, NotFoundException } from '@nestjs/common';
import { LoadStrategy, defineConfig } from '@mikro-orm/core';
import { SqlHighlighter } from '@mikro-orm/sql-highlighter';
import { TsMorphMetadataProvider } from '@mikro-orm/reflection';
import { PostgreSqlDriver } from '@mikro-orm/postgresql';
import { Migrator } from '@mikro-orm/migrations';
import 'dotenv/config';
const logger = new Logger('MikroORM');
const config = defineConfig({
entities: ['dist/**/*.entity.js'],
entitiesTs: ['src/**/*.entity.ts'],
driver: PostgreSqlDriver,
loadStrategy: LoadStrategy.JOINED,
clientUrl: 'postgresql://postgres:password@localhost:5432/db_name' as string,
highlighter: new SqlHighlighter(),
debug: true,
logger: logger.log.bind(logger),
metadataProvider: TsMorphMetadataProvider,
allowGlobalContext: true,
migrations: {
tableName: 'mikro_orm_migrations',
path: './migrations',
glob: '!(*.d).{js,ts}',
transactional: true,
disableForeignKeys: true,
allOrNothing: true,
dropTables: false,
safe: true,
emit: 'ts', // migration generation mode
},
extensions: [Migrator],
findOneOrFailHandler: (entityName) => {
throw new NotFoundException(`${entityName} not found`);
},
});
export default config;
3. Configure Mikro-ORM in app.module.ts:
import { Module } from '@nestjs/common';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import mikroOrmConfig from './mikro-orm.config';
@Module({
imports: [
MikroOrmModule.forRoot(mikroOrmConfig),
// Other modules
],
controllers: [],
providers: [],
})
export class AppModule {}
Defining Entities
Entities in Mikro-ORM are the models for your database tables. Let's define an example User entity.
1. Create `user.entity.ts` in the `src/entities` directory
import { Entity, PrimaryKey, Property } from '@mikro-orm/core';
@Entity()
export class User {
@PrimaryKey()
id!: number;
@Property()
name!: string;
@Property()
email!: string;
@Property()
createdAt = new Date();
}
2. Add mikro-orm dependency to `package.json`
"mikro-orm": {
"useTsNode": true,
"configPaths": [
"./src/mikro-orm.config.ts",
"./dist/mikro-orm.config.js"
]
}
3. Running Migrations
Migrations are essential for managing database schema changes. Mikro-ORM
provides a straightforward way to handle migrations.
Prerequisites
Install mikro-orm/cli
npm i @mikro-orm/cli
1. Create an initial migration:
npx mikro-orm migration:create
2. Run the migration:
npx mikro-orm migration:up
Conclusion
By leveraging NestJS with Mikro-ORM, we have a powerful setup for building scalable and maintainable applications. Mikro-ORM's rich feature set and seamless integration with NestJS enable us to manage our database operations efficiently. Whether you are starting a new project or looking to enhance your current setup, this combination provides a solid foundation for your application development needs.
For further reading and detailed configurations, refer to the following resources:
NestJS Documentation: https://docs.nestjs.com
Mikro-ORM Documentation: https://mikro-orm.io/docs/quick-start
Happy coding!
About Harish Bisu
Harish Bisu is an Intern at CyberMind Works, focusing on backend development. He is gaining practical experience and actively contributing to key backend projects within the development team.