Imagine You’re Building a Toy Store Database
Let’s say you have a toy store, and you want to keep track of all the toys you have, who buys them, and how much they cost. Now, instead of writing everything down in a notebook (which can get messy and hard to update), you decide to use a computer program. This program helps you save all your information neatly, search for specific toys, and even know when stock is running low.
NestJS is like the manager of this store. It knows how to organize everything and ensures the right actions happen when someone asks. Sequelize ORM (Object-Relational Mapping) acts like your translator—it understands both your language (JavaScript) and the database’s language (PostgreSQL). Together, they make your store run smoothly!
Table of Contents
Why Learn NestJS with Sequelize ORM and PostgreSQL?
NestJS is a progressive Node.js framework that is fast, reliable, and scalable. When paired with Sequelize ORM, it allows developers to interact with databases like PostgreSQL using JavaScript or TypeScript.
Benefits:
- Simplifies complex database queries.
- Helps in building clean, maintainable code.
- Supports advanced features like transactions and migrations.
- Ideal for modern applications like e-commerce, CMS, and enterprise software.
Setting Up NestJS with Sequelize ORM and PostgreSQL
Let’s dive into building an actual application step-by-step.
Step 1: Create a New NestJS Project
- Install NestJS CLI:bashCopy code
npm install -g @nestjs/cli
- Create a new project:bashCopy code
nest new toy-store cd toy-store
- Install Sequelize and PostgreSQL dependencies:bashCopy code
npm install @nestjs/sequelize sequelize sequelize-typescript pg pg-hstore
Step 2: Configure PostgreSQL Database Connection
Update your app.module.ts
to include Sequelize configuration.
import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
@Module({
imports: [
SequelizeModule.forRoot({
dialect: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'yourpassword',
database: 'toy_store',
autoLoadModels: true,
synchronize: true,
}),
],
})
export class AppModule {}
Step 3: Define Your First Model (Toy)
Create a toy.model.ts
file in the src/toy
directory.
import { Column, DataType, Model, Table } from 'sequelize-typescript';
@Table
export class Toy extends Model {
@Column({
type: DataType.STRING,
allowNull: false,
})
name: string;
@Column({
type: DataType.INTEGER,
allowNull: false,
})
price: number;
@Column({
type: DataType.STRING,
})
category: string;
}
Step 4: Build a Toy Service and Controller
Toy Service
Create a toy.service.ts
file:
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { Toy } from './toy.model';
@Injectable()
export class ToyService {
constructor(@InjectModel(Toy) private toyModel: typeof Toy) {}
async createToy(data: { name: string; price: number; category: string }) {
return this.toyModel.create(data);
}
async getAllToys() {
return this.toyModel.findAll();
}
}
Toy Controller
Create a toy.controller.ts
file:
import { Controller, Get, Post, Body } from '@nestjs/common';
import { ToyService } from './toy.service';
@Controller('toys')
export class ToyController {
constructor(private readonly toyService: ToyService) {}
@Post()
create(@Body() data: { name: string; price: number; category: string }) {
return this.toyService.createToy(data);
}
@Get()
findAll() {
return this.toyService.getAllToys();
}
}
Step 5: Add Jest Tests
Testing the Service:
import { Test, TestingModule } from '@nestjs/testing';
import { ToyService } from './toy.service';
import { getModelToken } from '@nestjs/sequelize';
import { Toy } from './toy.model';
describe('ToyService', () => {
let service: ToyService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ToyService,
{
provide: getModelToken(Toy),
useValue: {
create: jest.fn(),
findAll: jest.fn(),
},
},
],
}).compile();
service = module.get<ToyService>(ToyService);
});
it('should create a toy', async () => {
const createSpy = jest.spyOn(service, 'createToy');
await service.createToy({ name: 'Action Figure', price: 500, category: 'Figures' });
expect(createSpy).toHaveBeenCalled();
});
});
Best Practices for NestJS with Sequelize and PostgreSQL
- Database Security: Always use environment variables for database credentials.
- Model Relationships: Use Sequelize’s association methods (e.g.,
hasOne
,belongsTo
) for building complex schemas. - Transactions: Use transactions to maintain data consistency.
Common Mistakes to Avoid
- Hardcoding sensitive data in code.
- Forgetting to handle database connection errors.
- Ignoring Sequelize migrations for schema updates.
Interview Questions
- What is NestJS, and why is it used?
- NestJS is a progressive framework for building server-side applications. It’s used for its modular architecture and support for modern JavaScript/TypeScript.
- Explain Sequelize ORM.
- Sequelize ORM is a library that maps database tables to JavaScript objects, enabling developers to write queries in JavaScript.
- How does NestJS implement Dependency Injection (DI)?
- NestJS uses a provider-based DI system that allows injecting dependencies into classes and components.
- What are some advantages of using PostgreSQL over MySQL?
- PostgreSQL supports advanced features like JSONB, full-text search, and complex queries.
- How do you manage relationships in Sequelize ORM?
- By defining associations like
hasOne
,belongsTo
,hasMany
, andbelongsToMany
.
- By defining associations like
Companies That Ask About These Topics
- Google: Focuses on backend frameworks and ORM usage.
- Amazon: Questions on scalable APIs and databases.
- Microsoft: Testing frameworks and dependency injection.
- Infosys: Sequelize and database management concepts.
Conclusion
NestJS, Sequelize ORM, and PostgreSQL offer a powerful combination for building robust and maintainable server-side applications. By following this guide, you can confidently develop, test, and optimize your backend systems for real-world needs.