Nestjs는 Node.js를 위한 프레임워크로, Angular의 구문과 구조를 채용하여 만들어졌다. 이 프레임워크는 서버 사이드 어플리케이션을 구축하기 위한 보일러플레이트 코드를 제공한다.
Nestjs는 Express와 Fastify의 기능을 확장하여 제공하며, TypeScript로 작성되어 있어 타입 체크를 통해 코드 품질을 높일 수 있다. 또한, Angular의 구문과 구조를 도입하여 Angular 개발자들이 쉽게 사용할 수 있다.
Nestjs의 주요 기능은 다음과 같다.
애플리케이션의 기능을 모듈로 나눌 수 있다. 각 모듈은 별도로 테스트 가능하며, 재사용성이 높아진다. 이렇게 모듈화된 구조는 코드의 복잡성을 낮추고 유지보수성을 높인다.
Nestjs는 의존성 주입(Dependency Injection) 패턴을 적극적으로 활용한다. 이를 통해 객체 간의 의존성을 쉽게 관리할 수 있으며, 유지보수성이 높아집니다. 또한, 단위 테스트를 용이하게 만든다.
Express와 Fastify의 미들웨어를 사용할 수 있다. 이 기능을 통해 애플리케이션의 특정 구간에 로직을 삽입하거나 요청/응답 데이터를 가공할 수 있다.
Nestjs는 예외 처리를 간소화하고, 에러 핸들링을 쉽게 할 수 있다. 이를 통해 예외 상황에서도 원활한 애플리케이션 실행을 보장할 수 있다.
Nestjs는 WebSocket 프로토콜을 지원한다. 이를 통해 실시간으로 데이터를 주고받는 애플리케이션을 쉽게 구현할 수 있다.
더 자세한 내용을 보려면 Nestjs 공식 문서를 참고.
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
// 모듈 등록
const app = await NestFactory.create(AppModule);
// 모듈에 포트 등록
await app.listen(3000);
}
bootstrap();
루트 모듈이 하나 있고 나머지 모듈들을 루트 모듈에 추가한다.
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
**@Get(”:id”) 로직이 다른 @Get("파라미터") 로직 보다 위에 있으면 모든 파라미터를 id로 인식하기 때문에 동적 파라미터 로직은 아래 부분에 놓아야 한다.**
데코레이터 - @Get(url),@Post()
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
// controller 함수 인수로 들어가는 단어가 url endpoint
@Controller(endPoint)
export class AppController {
constructor(private readonly appService: AppService) {}
// Get 데코레이터를 이용
@Get()
getHello(): string {
return this.appService.getHello();
}
// url 경로 /hello
@Get('/hello')
sayHello(): string {
return 'hello';
}
// id parameter
@Get('/user/:id')
getUser(@Param(id: string) id:string) {
return `user ${id}`
}
}
@Param(인수) = req.params파라미터를 받을 것이라는 설정 및 어떤 형태의 파라미터 받을건지 설정
@Get('/user/:id')
getUser(@Param(id) userId:string) {
return `user ${userId}`
}
@Body(인수) = req.body@Post()
postUser(@Body('id') {}: User) {
return { id: '', name: '', password: '' };
}
@Query(인수) = req.query@Get('search')
searchProduct(@Query('name') searchingProduct): string {
return `찾는 상품은 ${searchingProduct} 입니다.`;
}
@Headers() = req.headers
@Get('/user/:id')
getUser(@Headers('authorization') authorization) {
return authorization // Bearer token
}
데이터베이스와 통신할 때 사용하는 비지니스 로직을 서비스 컴포넌트에 작성
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
// db와 통신해서 값 리턴 하는 로직 작성
return 'Hello World!';
}
}
throw new NotFoundException()not found일 때 nestjs 에서 제공하는 에러 처리 메서드
DTO는 Data Transfer Object의 약어로, 데이터 전송 객체를 의미DTO는 Request와 Response 객체에서 사용되는 데이터를 정의하는데 사용DTO는 클래스로 정의.Request와 Response 객체에서 사용되는 데이터를 클래스의 속성으로 정의하고, 각 속성에 대한 유효성 검사 규칙을 적용.Controller의 메서드에서 파라미터로 사용PartialType 메서드를 이용해서 createDTO의 값을 그대로 가져와서 쓸 수 있다. @npm i @nestjs/mapped-types ⇒ 수정은 create할 때 생성한 데이터의 타입과 같거나 더 적기 때문에 그대로 사용 가능예제
create-product.dto.ts
import { IsString } from 'class-validator';
export class CreateProductDto {
@IsString()
name: string;
@IsString()
description: string;
@IsNumber()
price: number;
}
// controller.ts
@Controller('products')
export class ProductsController {
constructor(private readonly productsService: ProductsService) {}
@Post()
async create(@Body() createProductDto: CreateProductDto) {
return this.productsService.create(createProductDto);
}
}
// partialType
export class UpdateProductDto extends PartialType(CreateUserDto) {}
Nestjs는 파이프라인(Pipeline)을 지원
Controller에서 들어오는 요청 데이터를 검증하고, 필터링하는 등의 작업을 처리.ValidationPipe와 TransformPipe 등 다양한 종류의 파이프라인이 제공됨ValidationPipe는 데이터를 검증하고, 유효하지 않은 데이터가 들어올 경우 예외를 발생시킴TransformPipe는 데이터를 변환하거나, 데이터 유형을 강제로 변경파이프라인은 main.ts 파일에서 app.useGlobalPipes() 메서드를 사용하여 전역으로 설정할 수 있다.
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(
new ValidationPipe({
whitelist: true, // DTO에 없는 프로퍼티는 제거 후 저장
forbidNonWhitelisted: true // DTO에 없는 프로퍼티가 있다면 HttpException 던짐
}),
);
await app.listen(3000);
}
bootstrap();
좋은 정보 감사합니다