그동안 express로 서버개발을 꽤많이 해왔고, 다른 커뮤니티를 찾아보지 않아도 느꼈던, express의 자유도는 오히려 장기적으로, 엔터프라이즈 용으로는 분리한 점이 느껴졌다.
중간중간 Nest의 핵심 개념과 기능들을 정리해 보고자 한다.
공식문서
공식문서는 아니지만, 검색시 노출이 많이되는 꽤 괜찬은 문서
DB연결하기
서버에서 가장중요한것이 DB와 연결된 API를 제공하는 것이라 생각한다.
인증, dto 이런것들 이 이후라고 생각한다.
mysql + typeorm 설치
npm install --save @nestjs/typeorm typeorm mysql2
docker db 설치
설치후 스키마도 하나 생성해준다.
docker run --name my-mysql -e MYSQL_ROOT_PASSWORD=1234 -d -p 3306:3306 mysql:latest
app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PostsModule } from './posts/posts.module';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: '1234',
database: 'kong',
synchronize: true,
keepConnectionAlive: true,
logging: 'all',
charset: 'utf8mb4',
autoLoadEntities: true,
}),
PostsModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
- type: db 종류
- host: db 주소
- port: db포트(mysql은 보통 3306)
- username: db 사용자이름
- password: db 사용자 비번
- database: db 데이터베이스 이름
- entities: 만든 엔티티들 여기에 넣기
- autoLoadEntities: true면 TypeOrmModule.forFeature에 넣은 엔티티들은 자동 연결됨
- synchronize: true면 entity에 따라 실제 db 테이블 재생성(기존 테이블 다 날라가니 주의)
- logging: true면 typeorm이 만들어주는 쿼리가 콘솔에 표시(개발 시에는 켜두는 게 매우 유용)
- keepConnectionAlive: true여야 핫 리로딩시에도 db 연결이 끊어지지 않음
- charset: db의 언어 설정(utf8mb4로 할것)
엔티티 생성(테이블 생성)
Repository pattern
TypeORM을 사용하는 패턴은 여러개가 있다. 그중에서 개인적으로 repository 패턴을 선호한다.(이유는 처음이걸로 접했으니까..)
각 Entity는 각각의 Repository(저장공간)이 있다.
Entity(테이블)정의
import {
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
@Entity()
export class Article {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column({ type: 'text' })
content: string;
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}
모듈, 컨트롤러, 서비스 생성하기
nest에서는 큰 기능 범주로 모듈을 나누고, 모듈 내에서 요청과 응답을 처리하는 controller, 비지니스로직이 들어가는 service 3가지로 구성된다.
nest g mo posts // 모듈 생성
nest g co posts // 컨트롤러 생성
nest g s posts // 서비스 생성
API 생성하기
provider는 단순히 @Injectable() 데코레이터 주석이 달린 클래스를 말한다. provider 객체는 런타임에 NestJS에 의해 다른 모듈로 주입될 수 있다.
provider는 service를 포함해 repository, factory, helper 등이 될 수 있다.
@Injectable() 데코레이터가 붙어있는 클래스는 constructor를 통해서 의존성을 주입할 수 있다. 이렇게 하면 클래스 내부에서 this를 통해서 해당 서비스에 접근할 수 있게 된다.
import { Controller, Get, Post } from '@nestjs/common';
import { PostsService } from './posts.service';
@Controller('posts')
export class PostsController {
constructor(private readonly postsService: PostsService) {}
@Get()
findAll() {
return this.postsService.findAll();
}
@Post()
create() {
return this.postsService.createOne();
}
}
import { Injectable } from '@nestjs/common';
@Injectable()
export class PostsService {
findAll() {
return 'findAll';
}
createOne() {
return 'create';
}
}
TypeORM Dependency Injection
Post데코레이터와 겹쳐서 Entity의 이름을 Article로 변경하였습니다
@Module({
imports: [TypeOrmModule.forFeature([Article])],
controllers: [PostsController],
providers: [PostsService],
})
import { Body, Controller, Get, Post } from '@nestjs/common';
import { PostsService } from './posts.service';
@Controller('posts')
export class PostsController {
constructor(private readonly postsService: PostsService) {}
@Get()
findAll() {
return this.postsService.findAll();
}
@Post()
create(@Body() body: any) {
return this.postsService.createOne(body);
}
}
조회, 생성
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Article } from '../entity/article.entity';
import { Repository } from 'typeorm';
@Injectable()
export class PostsService {
constructor(
@InjectRepository(Article)
private articleRepository: Repository<Article>,
) {}
findAll() {
return this.articleRepository.find();
}
async createOne(body) {
const { title, content } = body;
const newArticle = this.articleRepository.create({ title, content });
return this.articleRepository.save(newArticle);
}
}
수정,삭제
@Patch(':id')
update(@Param('id') id: string, @Body() body: any) {
return this.postsService.updateById(+id, body);
}
@Delete(':id')
remove(@Param('id') id: string) {
return this.postsService.removeById(+id);
}
updateById(id: number, body: any) {
return this.articleRepository.update(id, body);
}
removeById(id: number) {
return this.articleRepository.delete(id);
}
'Archive' 카테고리의 다른 글
CORS 와 Cookie (0) | 2022.07.31 |
---|---|
static 파일제공 & View Engine & React (0) | 2022.07.31 |
Cookie 와 session 으로 인증관리하기 (0) | 2022.07.31 |
TS 냐금냐금 - 6 (0) | 2022.07.30 |
TS 냐금냐금 - 4 (0) | 2022.07.30 |