Getting Started with Nest.js and MySQL Database Connection Using TypeORM
Nest.js is a progressive Node.js framework used for building efficient, scalable, and reliable server-side applications. It is built with modern JavaScript and uses TypeScript, which enables type-checking and helps in better code maintainability. TypeORM is a powerful object-relational mapping library that allows developers to easily map their database schemas to TypeScript classes. In this guide, we will learn how to get started with Nest.js and connect a MySQL database to it using TypeORM.
Step 1: Install Nest.js CLI
To get started with Nest.js, you first need to install its CLI tool globally on your machine. Open a command prompt or terminal and run the following command:
npm install -g @nestjs/cli
Step 2: Create a new Nest.js project
Once the CLI tool is installed, you can create a new Nest.js project by running the following command:
nest new project-name
Replace `project-name` with your desired project name. This will create a new Nest.js project with all the required boilerplate code.
Step 3: Install required dependencies
In order to use TypeORM and connect to a MySQL database, we need to install a few additional dependencies. Run the following command in your project directory to install them:
npm install --save @nestjs/typeorm typeorm mysql2
The `@nestjs/typeorm` package provides integration with Nest.js, Typeform is the TypeORM library itself, and `mysql2` is the MySQL driver for TypeORM.
Step 4: Configure database connection
Next, we need to configure the connection to our MySQL database. Open the `app.module.ts` file in your project root directory and add the following configuration:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
entities: [],
synchronize: true,
}),
],
})
export class AppModule {}
Replace the values for `username`, `password`, and `database`-name with your MySQL server details. The entities property specifies the location of our entity files and `synchronize` will synchronize the database schema with our entities on every application launch.
Step 5: Create a TypeORM entity
We now need to create a TypeORM entity that will represent our database table. To do this, we'll use the nest schematics and run the following script:
nest generate resource user
The `nest generate resource` command is used to generate a complete set of files and folders for a new resource in your application, including a `user.controller.ts`, a `user.service.ts`, a `user.module.ts`, and a data transfer object (DTO) class. This command can help speed up the development process by creating the basic scaffolding for a new resource, allowing developers to focus on implementing the business logic for the new feature.
It will also create a file called `user.entity.ts`. Navigate to the entity-file and replace the code with the following code:
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
firstName: string;
@Column()
lastName: string;
@Column()
email: string;
@Column()
password: string;
}
This will create a `User` entity with four columns: `id`, `firstName`, `lastName`, `email`, and `password`. The `@PrimaryGeneratedColumn()` ensures that the field is an auto-incremented integer value.
Step 6: Add the User as a feature in the UsersModule
In order for us to set up the created feature, we need to import `TypeOrmModule.forFeature([User])` in the imports of the auto-generated `UserModule`. The code should now look like this:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { User } from './user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
This module imports `TypeOrmModule` and uses it to specify that it will be managing the `User` entity. It also imports a `UserController` and a `UserService`, which we will create in the next steps.
Step 7: Navigate to the User-controller file
If you decided to generate the resource as an REST API, and to include CRUD logic the `user.controller.ts` should in this step have CRUD logic calling the `userService` file:
import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
findAll() {
return this.userService.findAll();
}
...
}
This controller defines a route `/users` that will return all the users from the database using the `UserService`.
Step 8: Query from the database with the repository
Now navigate the generated `user.service.ts` file, and ensure that you add the `@InjectRepository` in the constructor.
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UserService {
constructor(
@InjectRepository(User)
private readonly userRepository: Repository<User>,
) {}
findAll(): Promise<User[]> {
return this.userRepository.find();
}
...
}
This service uses the `@InjectRepository` decorator from `@nestjs/typeorm` to inject the `User` repository and provides a `findAll()` method that will return all the users from the database.
Step 9: Update the main.ts file
Finally, we need to update the `main.ts` file in the `src` directory to register the `ValidationPipe` globally. in NestJS, `ValidationPipe` is a built-in middleware that helps to validate incoming request payloads against a defined class-validator schema.
When a request is received, ValidationPipe automatically applies the validation rules to the request payload according to the specified class-validator schema. If any validation errors occur, the pipe throws a BadRequestException with the details of the validation errors, which can then be handled by a custom exception filter.
Here is an example of how to add the ValidationPipe globally for all controllers:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
}
bootstrap();
This will create a new Nest.js application using the `AppModule`, use a `ValidationPipe` for input validation, and listen on port 3000.
Step 10: Test the application
To test the application, run the following command in your project directory:
npm run start
This will start the Nest.js application and connect to the MySQL database. You should see a message indicating that the application is running on port 3000. You can then navigate to `http://localhost:3000/users` in your browser to see a list of all the users in the database.
Congratulations, you have now successfully created a Nest.js application and connected it to a MySQL database using TypeORM!