본문 바로가기
Back-end/NestJS

[NestJS] Controller 패턴

by 며루치꽃 2022. 1. 7.
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}

Controller를 우선 살펴보자.

Controller는 AppService를 사용하게 만든다.

appService에 있는 getHello()의 리턴 값이 그대로 컨트롤러에 리턴이 되고, 그대로 컨트롤러에 있는 getHello() 가 리턴이 된다. 

 

그런데 의문점이 드는 것이 있다.

 

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return 'hello world';
  }
}

Q. appService의 getHello()는 리턴을 해주면 return 'hello world'; 과 같이 리턴을 해줄텐데 왜 굳이 '의존성 주입'까지  appService를 이용하여 리턴을 할까? 

express에서도 route랑 서비스를 분리를 하였다. 그 이유는 유지보수, 가독성, 디자인 패턴에 맞게 하기 위해 분리를 한 것이다. 그리고 전체적으로 NestJS는 모듈단위로 이동을 한다. 하나 하나 구성하는 것들이 클래스이고 클래스가 레고처럼 결합하여 모듈처럼 되고, 이 모듈들이 여러개가 존재하고, 이 모듈들이 하나의 모듈로 합쳐져서 메인에서 실행이 되는 구조이다. 그렇기 때문에 이런 디자인 패턴 자체를 사용을 하는 것이다. 

 

컨트롤러의 역할

공식 문서에는 컨트롤러의 목적은 다음과 같이 기술되어있다. 아래를 보자

컨트롤러의 목적은 애플리케이션에 대한 특정 요청을 수신하는 것입니다. 라우팅 메커니즘은 어떤 컨트롤러가 어떤 요청을 수신하는지 제어합니다. 종종 각 컨트롤러에는 둘 이상의 라우트가 있으며 다른 라우트는 다른 작업을 수행할 수 있습니다.

기본 컨트롤러를 만들기 위해 클래스와 데코레이터를 사용합니다. 데코레이터는 클래스를 필수 메타데이터와 연결하고 Nest가 라우팅 맵을 만들 수 있도록 합니다(요청을 해당 컨트롤러에 연결).

 

라우팅

import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller('cats')
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('hello')
  getHello(): string {
    return this.appService.getHello();
  }
}

@Controller 데코레이터에 선택적 라우트 경로 접두사인 'cats'를 넣게 된다면 엔드포인트가 수정이 되고 라우트 집합을 쉽게 그룹화하고 반복코드를 최소화할 수 있다.

그룹화 한다는 말은, express의 다음코드를 보자

router.get('/cats', readAllcat);
router.get('/cats/:id', readCat);
router.post('/cats', createCat);

다음과 같이 재사용성을 고려하지 않고, 앞에다가 동일하게 라우트 경로 /cats 가 들어가는데 이를 @Controller 데코레이터에 선택적 라우트 경로 접두사인 'cats'를 넣게 되면 
1. 컨트롤러가 'cats'라는 컨트롤러를 찾는다

2. 그 컨트롤러 안에 해당하는 메서드가 있는 엔드포인트를 따라간다

3. @Get('hello')는 GET 메서드의 /cats/hello 로 라우트 매핑을 한다 

 

요청 개체

express에서 서비스에서 req, res로 인자를 받아서 해당하는 req에 대한 정보 예를 들어 req.body이면 요청 안에 있는 body를 이용하고 params를 이용하고 이런 식으로 서비스 로직을 만들었다. 

NestJS에서도 이와 유사하게 만들 수 있다. 

express에서 다음과 같이 이용하였다면

const body = req.body
const data = req.params

 

NestJS에서는 인자에서 받을 수 있다. 

 

import { Body, Controller, Get, Param, Req } from '@nestjs/common';
import { Request } from 'express';
import { AppService } from './app.service';

@Controller('cats')
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get('hello/:id/:name')
  getHello(@Req() req: Request, @Body() Body, @Param() param: {id: string; name: string}): string {
    console.log(param)
    return this.appService.getHello();
  }

}

예를 들어 /cats/hello/123/eric이라면 11번째 줄 console.log(param)에는 { id:123, name: 'eric' } 으로 나오게 된다.

'Back-end > NestJS' 카테고리의 다른 글

[NestJS] NestJS의 시작  (0) 2021.12.29

댓글