NestJS with MySQL Integration and Usage
Integrating NestJS with a MySQL database is typically achieved using TypeORM or directly with the MySQL driver. This section demonstrates how to use TypeORM to connect to a MySQL database and perform basic CRUD operations.
Installing Dependencies
Install the required dependencies for TypeORM and MySQL support:
npm install --save @nestjs/typeorm typeorm mysql2 reflect-metadataConfiguring Database Connection
Configure TypeORM to connect to the MySQL database, typically in a file like ormconfig.json:
// ormconfig.json
{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "yourpassword",
"database": "testdb",
"synchronize": true, // Note: Do not use this in production
"logging": false,
"entities": [
"src/**/*.entity{.ts,.js}"
],
"migrations": [
"src/migration/*{.ts,.js}"
],
"subscribers": [
"src/subscriber/*{.ts,.js}"
],
"cli": {
"entitiesDir": "src",
"migrationsDir": "src/migration",
"subscribersDir": "src/subscriber"
}
}Creating an Entity
Entities in TypeORM map to database tables. Create a simple User entity:
// src/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@Column()
password: string;
}Creating a Service
Create a service to handle database interactions:
// src/users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}
async findAll(): Promise<User[]> {
return this.usersRepository.find();
}
async findOne(id: number): Promise<User | undefined> {
return this.usersRepository.findOneBy({ id });
}
async create(user: User): Promise<User> {
return this.usersRepository.save(user);
}
async update(id: number, user: User): Promise<void> {
await this.usersRepository.update(id, user);
}
async delete(id: number): Promise<void> {
await this.usersRepository.delete(id);
}
}Creating a Controller
Create a controller to handle HTTP requests:
// src/users.controller.ts
import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './user.entity';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string): Promise<User | undefined> {
return this.usersService.findOne(+id);
}
@Post()
create(@Body() user: User): Promise<User> {
return this.usersService.create(user);
}
@Put(':id')
update(@Param('id') id: string, @Body() user: User): Promise<void> {
return this.usersService.update(+id, user);
}
@Delete(':id')
remove(@Param('id') id: string): Promise<void> {
return this.usersService.delete(+id);
}
}Registering the Module
Register the module and import the TypeORM module to establish the database connection:
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'yourpassword',
database: 'testdb',
entities: [User],
synchronize: true, // Note: Do not use this in production
logging: false,
}),
UsersModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}Running the Application
Start the NestJS application:
npm run start:devVisit http://localhost:3000/users to view all user information.
NestJS with PostgreSQL Integration and Usage
Integrating PostgreSQL with NestJS is typically done using TypeORM or Prisma. This section focuses on using TypeORM.
Installing Dependencies
Install TypeORM and PostgreSQL dependencies:
npm install --save @nestjs/typeorm typeorm pg reflect-metadataConfiguring Database Connection
Configure TypeORM to connect to PostgreSQL in ormconfig.json:
// ormconfig.json
{
"type": "postgres",
"host": "localhost",
"port": 5432,
"username": "your_username",
"password": "your_password",
"database": "your_database",
"synchronize": true, // Note: Do not use this in production
"logging": false,
"entities": [
"src/**/*.entity{.ts,.js}"
],
"migrations": [
"src/migration/*{.ts,.js}"
],
"subscribers": [
"src/subscriber/*{.ts,.js}"
],
"cli": {
"entitiesDir": "src",
"migrationsDir": "src/migration",
"subscribersDir": "src/subscriber"
}
}Creating an Entity
Create a User entity:
// src/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@Column()
password: string;
}Creating a Service
Create a service for database interactions:
// src/users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}
async findAll(): Promise<User[]> {
return this.usersRepository.find();
}
async findOne(id: number): Promise<User | undefined> {
return this.usersRepository.findOneBy({ id });
}
async create(user: User): Promise<User> {
return this.usersRepository.save(user);
}
async update(id: number, user: User): Promise<void> {
await this.usersRepository.update(id, user);
}
async delete(id: number): Promise<void> {
await this.usersRepository.delete(id);
}
}Creating a Controller
Create a controller for HTTP requests:
// src/users.controller.ts
import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './user.entity';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string): Promise<User | undefined> {
return this.usersService.findOne(+id);
}
@Post()
create(@Body() user: User): Promise<User> {
return this.usersService.create(user);
}
@Put(':id')
update(@Param('id') id: string, @Body() user: User): Promise<void> {
return this.usersService.update(+id, user);
}
@Delete(':id')
remove(@Param('id') id: string): Promise<void> {
return this.usersService.delete(+id);
}
}Registering the Module
Register the module and import TypeORM:
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './users/user.entity';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'your_username',
password: 'your_password',
database: 'your_database',
entities: [User],
synchronize: true, // Note: Do not use this in production
logging: false,
}),
UsersModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}Running the Application
Start the application:
npm run start:devVisit http://localhost:3000/users to view all user information.
NestJS with MongoDB Integration and Usage
Integrating MongoDB with NestJS is typically done using Mongoose, a MongoDB object modeling tool that provides a straightforward API.
Installing Dependencies
Install Mongoose and its NestJS support:
npm install --save @nestjs/mongoose mongooseConfiguring Database Connection
Configure Mongoose to connect to MongoDB in database.config.ts:
// database.config.ts
import { Connection, connect } from 'mongoose';
export const databaseConfig = {
uri: 'mongodb://localhost:27017/testdb',
};
export async function connectToDatabase(config: typeof databaseConfig): Promise<Connection> {
const connection = await connect(config.uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
console.log('Connected to MongoDB');
return connection;
}Creating a Module
Create a module to manage the database connection:
// database.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { connectToDatabase, databaseConfig } from './database.config';
@Module({
imports: [
MongooseModule.forRootAsync({
useFactory: () => databaseConfig,
}),
],
})
export class DatabaseModule {}Creating Schema and Model
Define a Schema and Model for the data structure:
// user.schema.ts
import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
export type UserDocument = User & Document;
@Schema()
export class User {
@Prop()
username: string;
@Prop()
password: string;
}
export const UserSchema = SchemaFactory.createForClass(User);Creating a Service
Create a service for database interactions:
// users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User, UserDocument } from './user.schema';
@Injectable()
export class UsersService {
constructor(@InjectModel(User.name) private userModel: Model<UserDocument>) {}
async findAll(): Promise<User[]> {
return this.userModel.find().exec();
}
async findOne(id: string): Promise<User | null> {
return this.userModel.findById(id).exec();
}
async create(user: User): Promise<User> {
const createdUser = new this.userModel(user);
return createdUser.save();
}
async update(id: string, user: User): Promise<User | null> {
return this.userModel.findByIdAndUpdate(id, user, { new: true }).exec();
}
async delete(id: string): Promise<User | null> {
return this.userModel.findByIdAndDelete(id).exec();
}
}Creating a Controller
Create a controller for HTTP requests:
// users.controller.ts
import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './user.schema';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string): Promise<User | null> {
return this.usersService.findOne(id);
}
@Post()
create(@Body() user: User): Promise<User> {
return this.usersService.create(user);
}
@Put(':id')
update(@Param('id') id: string, @Body() user: User): Promise<User | null> {
return this.usersService.update(id, user);
}
@Delete(':id')
remove(@Param('id') id: string): Promise<User | null> {
return this.usersService.delete(id);
}
}Registering the Module
Register the module and import Mongoose:
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { DatabaseModule } from './database/database.module';
@Module({
imports: [DatabaseModule, UsersModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}Running the Application
Start the application:
npm run start:devVisit http://localhost:3000/users to view all user information.
NestJS with Redis Integration and Usage
Integrating Redis with NestJS can be done using the @nestjs/redis module or third-party libraries like ioredis. This section uses @nestjs/redis.
Installing Dependencies
Install the required dependencies:
npm install --save @nestjs/redis ioredisConfiguring Redis
Configure Redis connection options in redis.config.ts:
// redis.config.ts
import { RedisOptions } from '@nestjs/redis';
export const redisConfig: RedisOptions = {
url: 'redis://localhost:6379',
};Creating a Redis Module
Create a module to manage Redis connections:
// redis.module.ts
import { Module } from '@nestjs/common';
import { RedisModule } from '@nestjs/redis';
import { redisConfig } from './redis.config';
@Module({
imports: [RedisModule.register(redisConfig)],
exports: [RedisModule],
})
export class RedisModule {}Creating a Redis Service
Create a service to encapsulate common Redis operations:
// redis.service.ts
import { Injectable, Logger } from '@nestjs/common';
import { ClientRedis } from '@nestjs/redis';
@Injectable()
export class RedisService {
constructor(private readonly client: ClientRedis, private readonly logger: Logger) {}
async set(key: string, value: string, ttl?: number): Promise<void> {
await this.client.set(key, value, 'EX', ttl || 60);
this.logger.log(`Set key ${key} with value ${value}`);
}
async get(key: string): Promise<string | null> {
const value = await this.client.get(key);
this.logger.log(`Got key ${key} with value ${value}`);
return value;
}
async del(key: string): Promise<number> {
const result = await this.client.del(key);
this.logger.log(`Deleted key ${key}`);
return result;
}
}Registering the Redis Module
Register the Redis module in the main module:
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { RedisModule } from './redis/redis.module';
@Module({
imports: [RedisModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}Using the Redis Service
Inject and use the RedisService in a controller:
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { RedisService } from './redis/redis.service';
@Controller()
export class AppController {
constructor(private readonly redisService: RedisService) {}
@Get('/set')
async setRedisKey(): Promise<void> {
await this.redisService.set('test', 'Hello, Redis!');
}
@Get('/get')
async getRedisKey(): Promise<string | null> {
return await this.redisService.get('test');
}
@Get('/del')
async delRedisKey(): Promise<number> {
return await this.redisService.del('test');
}
}Running the Application
Start the application:
npm run start:devVisit http://localhost:3000/set to set a Redis key-value pair, http://localhost:3000/get to retrieve it, and http://localhost:3000/del to delete it.
NestJS with TypeORM Integration and Usage
Integrating TypeORM with NestJS enables interaction with various relational databases. This section provides a comprehensive guide.
Installing Dependencies
Install TypeORM and the MySQL driver:
npm install --save @nestjs/typeorm typeorm mysql2Configuring Database Connection
Configure TypeORM in ormconfig.json:
// ormconfig.json
{
"type": "mysql",
"host": "localhost",
"port": 3306,
"username": "root",
"password": "your_password",
"database": "your_database",
"synchronize": true, // Note: Do not use this in production
"logging": false,
"entities": [
"src/**/*.entity{.ts,.js}"
],
"migrations": [
"src/migration/*{.ts,.js}"
],
"subscribers": [
"src/subscriber/*{.ts,.js}"
],
"cli": {
"entitiesDir": "src",
"migrationsDir": "src/migration",
"subscribersDir": "src/subscriber"
}
}Creating an Entity
Create a User entity:
// src/user.entity.ts
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
username: string;
@Column()
password: string;
}Creating a Service
Create a service for database interactions:
// src/users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) {}
async findAll(): Promise<User[]> {
return this.usersRepository.find();
}
async findOne(id: number): Promise<User | undefined> {
return this.usersRepository.findOneBy({ id });
}
async create(user: User): Promise<User> {
return this.usersRepository.save(user);
}
async update(id: number, user: User): Promise<void> {
await this.usersRepository.update(id, user);
}
async delete(id: number): Promise<void> {
await this.usersRepository.delete(id);
}
}Creating a Controller
Create a controller for HTTP requests:
// src/users.controller.ts
import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from './user.entity';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string): Promise<User | undefined> {
return this.usersService.findOne(+id);
}
@Post()
create(@Body() user: User): Promise<User> {
return this.usersService.create(user);
}
@Put(':id')
update(@Param('id') id: string, @Body() user: User): Promise<void> {
return this.usersService.update(+id, user);
}
@Delete(':id')
remove(@Param('id') id: string): Promise<void> {
return this.usersService.delete(+id);
}
}Registering the Module
Register the module and import TypeORM:
// src/users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'your_password',
database: 'your_database',
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true, // Note: Do not use this in production
logging: false,
}),
UsersModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}Running the Application
Start the application:
npm run start:devVisit http://localhost:3000/users to view all user information.
TypeORM Transactions
TypeORM supports transactions using the @Transactional decorator or the EntityManager transaction method:
// src/users/users.service.ts
import { Injectable, InjectRepository } from '@nestjs/common';
import { Repository, EntityManager, Connection, Transactional } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private userRepository: Repository<User>,
private connection: Connection,
) {}
@Transactional()
async createUserAndProfile(user: User): Promise<User> {
const entityManager: EntityManager = this.connection.manager;
try {
const newUser = await entityManager.save(user);
// Assume Profile is another entity
const profile = new Profile();
profile.user = newUser;
await entityManager.save(profile);
return newUser;
} catch (error) {
throw error;
}
}
async createUserAndProfileWithTransaction(user: User): Promise<User> {
return this.connection.transaction(async (entityManager) => {
const newUser = await entityManager.save(user);
// Assume Profile is another entity
const profile = new Profile();
profile.user = newUser;
await entityManager.save(profile);
return newUser;
});
}
}Unit Testing
Write unit tests to ensure services and controllers work as expected:
Install testing dependencies:
npm install --save-dev jest @types/jest ts-jestConfigure Jest in jest.config.js:
// jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src'],
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
};Create a test file users.service.spec.ts:
// src/users/users.service.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { UsersService } from './users.service';
import { User } from './user.entity';
import { Repository } from 'typeorm';
import { getRepositoryToken } from '@nestjs/typeorm';
describe('UsersService', () => {
let service: UsersService;
let repository: Repository<User>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UsersService,
{
provide: getRepositoryToken(User),
useValue: {
find: jest.fn(),
findOneBy: jest.fn(),
save: jest.fn(),
update: jest.fn(),
delete: jest.fn(),
},
},
],
}).compile();
service = module.get<UsersService>(UsersService);
repository = module.get<Repository<User>>(getRepositoryToken(User));
});
describe('findAll', () => {
it('should return an array of users', async () => {
const users = [{ id: 1, username: 'test', password: 'test' }];
jest.spyOn(repository, 'find').mockResolvedValue(users);
expect(await service.findAll()).toBe(users);
});
});
// Additional test cases...
});Integration Testing
For complex tests, use integration testing to simulate the entire system:
Create an integration test file users.integration.spec.ts:
// src/users/users.integration.spec.ts
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import * as request from 'supertest';
import { AppModule } from '../app.module';
import { User } from './user.entity';
describe('Users (e2e)', () => {
let app: INestApplication;
beforeAll(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
afterAll(async () => {
await app.close();
});
describe('GET /users', () => {
it('should return all users', () => {
return request(app.getHttpServer())
.get('/users')
.expect(200)
.then((response) => {
expect(response.body).toEqual(expect.arrayContaining([
expect.objectContaining({
id: expect.any(Number),
username: expect.any(String),
password: expect.any(String),
})
]));
});
});
});
// Additional test cases...
});Deployment
Deploy NestJS applications using Docker, Heroku, AWS, etc. Here’s an example with Docker:
Create Dockerfile:
# Dockerfile
FROM node:14-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "run", "start"]Build Docker Image:
docker build -t your-image-name .Run Docker Container:
docker run -p 3000:3000 your-image-nameNestJS with Sequelize Integration and Usage
Integrating Sequelize with NestJS enables interaction with relational databases. This section provides a comprehensive guide.
Installing Dependencies
Install Sequelize and the MySQL driver:
npm install --save @nestjs/sequelize sequelize sequelize-cli mysql2Install Sequelize CLI for development:
npx sequelize-cli initThis creates a basic folder structure and configuration files.
Configuring Database Connection
Configure Sequelize in config/config.json:
// config/config.json
{
"development": {
"username": "root",
"password": "your_password",
"database": "your_database",
"host": "localhost",
"dialect": "mysql"
},
"test": {
"username": "root",
"password": "your_password",
"database": "your_database",
"host": "localhost",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": "your_password",
"database": "your_database",
"host": "localhost",
"dialect": "mysql"
}
}Creating a Model
Models in Sequelize map to database tables. Create a User model:
// src/models/user.model.ts
import { Table, Column, Model, DataType, AllowNull, PrimaryKey, AutoIncrement } from 'sequelize-typescript';
@Table
export class User extends Model<User> {
@AllowNull(false)
@PrimaryKey
@AutoIncrement
@Column(DataType.INTEGER)
id: number;
@AllowNull(false)
@Column(DataType.STRING)
username: string;
@AllowNull(false)
@Column(DataType.STRING)
password: string;
}Creating a Service
Create a service for database interactions:
// src/users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from '../models/user.model';
@Injectable()
export class UsersService {
constructor(
@InjectModel(User)
private userModel: typeof User,
) {}
async findAll(): Promise<User[]> {
return this.userModel.findAll();
}
async findOne(id: number): Promise<User | null> {
return this.userModel.findByPk(id);
}
async create(user: User): Promise<User> {
return this.userModel.create(user);
}
async update(id: number, user: User): Promise<[number]> {
return this.userModel.update(user, { where: { id } });
}
async delete(id: number): Promise<number> {
return this.userModel.destroy({ where: { id } });
}
}Creating a Controller
Create a controller for HTTP requests:
// src/users.controller.ts
import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { UsersService } from './users.service';
import { User } from '../models/user.model';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll(): Promise<User[]> {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string): Promise<User | null> {
return this.usersService.findOne(+id);
}
@Post()
create(@Body() user: User): Promise<User> {
return this.usersService.create(user);
}
@Put(':id')
update(@Param('id') id: string, @Body() user: User): Promise<[number]> {
return this.usersService.update(+id, user);
}
@Delete(':id')
remove(@Param('id') id: string): Promise<number> {
return this.usersService.delete(+id);
}
}Registering the Module
Register the module and import Sequelize:
// src/users.module.ts
import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { User } from '../models/user.model';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
imports: [SequelizeModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
// src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
import { SequelizeModule } from '@nestjs/sequelize';
@Module({
imports: [
SequelizeModule.forRoot({
dialect: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'your_password',
database: 'your_database',
models: [__dirname + '/**/*.model{.ts,.js}'],
autoLoadModels: true,
synchronize: true, // Note: Do not use this in production
logging: false,
}),
UsersModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}Running the Application
Start the application:
npm run start:devVisit http://localhost:3000/users to view all user information.
Sequelize Transactions
Sequelize supports transactions using the sequelize.transaction() method:
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';
import { Model, Sequelize } from 'sequelize';
@Injectable()
export class UsersService {
constructor(
@InjectModel(User)
private userModel: typeof User,
private sequelize: Sequelize,
) {}
async createUserAndProfile(user: User): Promise<User> {
return this.sequelize.transaction(async (t) => {
try {
const newUser = await this.userModel.create(user, { transaction: t });
// Assume Profile is another model
const profile = new Profile();
profile.userId = newUser.id;
await profile.save({ transaction: t });
return newUser;
} catch (error) {
throw error;
}
});
}
}NestJS with Prisma Integration and Usage
Integrating Prisma with NestJS simplifies interaction with relational databases. This section provides a comprehensive guide.
Installing Dependencies
Install Prisma and the PostgreSQL driver:
npm install --save prisma @prisma/clientInstall Prisma CLI for development:
npx prisma@latest --version
npx prisma generateOptionally, install Prisma CLI globally:
npm install -g prismaConfiguring Prisma
Configure Prisma to connect to PostgreSQL in prisma/schema.prisma:
// prisma/schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
username String @unique
password String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}Generating Prisma Client
Generate the Prisma client:
npx prisma generateThis creates the Prisma client in node_modules/@prisma/client.
Creating a Service
Create a service for database interactions:
// src/users/users.service.ts
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class UsersService implements OnModuleInit, OnModuleDestroy {
constructor(private prisma: PrismaClient) {}
onModuleInit() {
this.prisma.$connect();
}
onModuleDestroy() {
this.prisma.$disconnect();
}
async findAll(): Promise<any[]> {
return this.prisma.user.findMany();
}
async findOne(id: number): Promise<any | null> {
return this.prisma.user.findUnique({ where: { id } });
}
async create(data: any): Promise<any> {
return this.prisma.user.create({ data });
}
async update(id: number, data: any): Promise<any> {
return this.prisma.user.update({ where: { id }, data });
}
async delete(id: number): Promise<any> {
return this.prisma.user.delete({ where: { id } });
}
}Creating a Controller
Create a controller for HTTP requests:
// src/users/users.controller.ts
import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
findAll(): Promise<any[]> {
return this.usersService.findAll();
}
@Get(':id')
findOne(@Param('id') id: string): Promise<any | null> {
return this.usersService.findOne(+id);
}
@Post()
create(@Body() user: any): Promise<any> {
return this.usersService.create(user);
}
@Put(':id')
update(@Param('id') id: string, @Body() user: any): Promise<any> {
return this.usersService.update(+id, user);
}
@Delete(':id')
remove(@Param('id') id: string): Promise<any> {
return this.usersService.delete(+id);
}
}Registering the Module
Register the module and set up Prisma:
// src/users/users.module.ts
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
@Module({
imports: [],
controllers: [UsersController],
providers: [UsersService, PrismaService],
exports: [PrismaService],
})
export class UsersModule {}
// src/prisma.service.ts
import { Injectable, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy {
constructor() {
super();
}
onModuleInit() {
this.$connect();
}
onModuleDestroy() {
this.$disconnect();
}
}
// src/app.module.ts
import { Module } from '@nestjs/common';
import { UsersModule } from './users/users.module';
import { PrismaService } from './prisma.service';
@Module({
imports: [UsersModule],
controllers: [],
providers: [PrismaService],
})
export class AppModule {}Running the Application
Start the application:
npm run start:devVisit http://localhost:3000/users to view all user information.
Prisma Transactions
Prisma 2.x introduced transaction support:
// src/users/users.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Injectable()
export class UsersService {
constructor(private prisma: PrismaService) {}
async createUserAndProfile(user: any): Promise<any> {
return this.prisma.$transaction(async (tx) => {
try {
const newUser = await tx.user.create({ data: user });
// Assume Profile is another model
const profile = await tx.profile.create({ data: { userId: newUser.id } });
return newUser;
} catch (error) {
throw error;
}
});
}
}



