Build backend project using nestjs, mysql, graphql, nextjs, docker-compose
Trong bài viết này, chúng ta sẽ tìm hiểu cách sử dụng NestJS, MySQL và GraphQL để xây dựng một backend server.
1.Giới thiệu qua các công nghệ
NestJS là một framework Node.js được phát triển trên kiến trúc của Angular, giúp cho việc phát triển ứng dụng backend Node.js trở nên dễ dàng hơn.
MySQL là một hệ quản trị cơ sở dữ liệu phổ biến được sử dụng rộng rãi trong các ứng dụng web.
GraphQL là một ngôn ngữ truy vấn được phát triển bởi Facebook, cho phép các ứng dụng client truy vấn dữ liệu một cách linh hoạt và hiệu quả.
2.Khởi tạo ứng dụng nestjs
Mình sẽ làm theo các bước trong document sau
https://docs.nestjs.com/first-stepscài đặt nestjs-cli
npm i -g @nestjs/cli
khở tạo nestjs project bằng câu lệnh
nest new project-name
câu lệnh trên sẽ tạo ra một folder có tên là project-name chứa source code do nest-cli sinh ra.
Run thử server bằng một trong hai câu lệnh sau, và truy cập vào http://localhost:3000/ để xem thử response trả về.
npm run start
hoặc nếu muốn server tự restart khi nội dung file thay đổi thì chạy câu lệnh
npm run start:dev
Tất cả các câu lệnh này đều được ghi tại file package.json.
3.Tạo docker-compose file
Hệ thống backend trong bài này sẽ gồm 2 service là server và mysql. Server ta đã khởi tạo ở trên. Tiếp theo ta sẽ tạo một mysql server dùng docker.
File docker-compose sẽ có dạng như sau:
version: "3"
services:
server:
build:
context: ../project-name --> name of backend folder
dockerfile: Dockerfile
environment:
DB_USERNAME: <-your-db-user->
DB_PASSWORD: <-your-db-password->
DB_HOST: mysql
DB_DATABASE: <-db-name->
volumes:
- /usr/src/app/node_modules
ports:
- 3001:3001
mysql:
image: mysql:8.0.24
container_name: mysql
environment:
MYSQL_ROOT_PASSWORD: <-your-db-password->
MYSQL_DATABASE: <-db-name->
volumes:
- ./docker/mysql/data:/var/lib/mysql
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/my.cnf
- ./docker/mysql/initdata:/docker-entrypoint-initdb.d
ports:
- 3306:3306
4.Config nestjs server connect tới mysql
Ta sẽ làm theo tài liệu dưới đây để setup database connection.
https://docs.nestjs.com/techniques/databaseThư viện typeorm được sử dụng để thao tác với dữ liệu từ DB.
Cài đặt thư viện cần thiết:
npm install --save @nestjs/typeorm typeorm mysql2
Thêm config database vào file app.module.ts:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: '<-your-db-user->',
password: '<-your-db-password->',
database: '<-db-name->',
entities: [<-your-tables->],
synchronize: true,
}),
],
})
export class AppModule {}
synchronize: true sẽ tự động migrate DB khi ta sửa file model.
5. Config graphql
Ta sẽ làm theo tài liệu dưới đây để setup graphql cho project.
https://docs.nestjs.com/graphql/quick-startInstall thư viện cần thiết
npm i @nestjs/graphql @nestjs/apollo @apollo/server graphql
Thêm config sau vào app.module.ts
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
debug: false,
playground: true,
autoSchemaFile: join(process.cwd(), 'src/schema.gql')
}),
],
})
export class AppModule {}
Option playground: true giúp ta có thể mở ra trang giao diện để thao tác với các graphql API thông qua địa chỉ sau http://localhost:3000/graphql.
Tiếp theo ta sẽ tạo một module và resolver cho module đó như hướng dẫn dưới đây.
https://docs.nestjs.com/graphql/resolversTạo file author.model.ts
import { Field, ID, Int, ObjectType } from '@nestjs/graphql';
import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm';
@ObjectType()
@Entity()
export class Author {
@PrimaryGeneratedColumn('increment')
@Field((type) => ID)
readonly id?: number;
@Column({ length: 32 })
@Index({ unique: true })
@Field()
public name: string;
}
Tạo file authors.resolver.ts
@Resolver(of => Author)
export class AuthorsResolver {
constructor(
private authorsService: AuthorsService,
) {}
@Query(returns => Author, { name: 'author' })
async getAuthor(@Args('id', { type: () => Int }) id: number) {
return this.authorsService.findOneById(id);
}
}
Tạo file authors.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Author } from './author.model';
@Injectable()
export class AuthorsService {
constructor(
@InjectRepository(Author)
private authorsRepository: Repository<Author>,
) {}
findOneById(id: number): Promise<Author> {
return this.authorsRepository.findOneBy({ id });
}
}
Tạo file authors.module.ts
@Module({
imports: [PostsModule],
providers: [AuthorsService, AuthorsResolver],
})
export class AuthorsModule {}
Import author module vào app.module.ts
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
debug: false,
playground: true,
autoSchemaFile: join(process.cwd(), 'src/schema.gql')
}),
AuthorsModule,
],
})
export class AppModule {}
Như vậy ta đã code xong các file cần thiết. Ta có thể mở playground để thao tác thử với query graphql vừa tạo.
Kết luận
Bài viết đã trình bày các bước để xây dựng một project backend bằng các công nghệ nestjs, graphql, mysql, docker-compose.
Trong bài tiếp theo, mình sẽ tạo một project front-end dùng nextjs để giao tiếp với server đã xây dựng.