[NestJS] Controller

yongkini ·2023년 4월 10일
0

NestJS

목록 보기
1/2

controller 란

  • controller는 router라고 생각하면 편하다. 그럼 라우터는 뭐냐 말그대로 라우팅을 해주는 뭔가 라고 생각하면 된다. 좀더 구체적으로 말해보면, 패킷이라는 데이터 단위를 이용해서 한 네트워크에서 다른 네트워크로 전송할 수 있도록 하는 것이다(2개 이상의 네트워크). 이 때, 라우팅이란 라우터가 패킷을 전달하기 위해 사용하는 '경로 선택 과정'이다. 라우터가 패킷이라는 데이터 단위로 데이터를 전송할 때 '최적의 경로 찾기(라우팅)'를 해야 효율적으로 전달이 가능하다. 그리고 마지막으로 라우트란(route) 라우터가 선택한(라우팅) 최적의 경로이다. 그럼 결론적으로 controller는 라우터라는 말을 풀어써보면, 컨트롤러는 패킷이라는 데이터 단위를 사용해서 네트워크에서 네트워크로 전송하는 역할을 하며 이 때, 라우팅(최적의 경로 선택 과정)을 거쳐서 선택한 라우트를 바탕으로 전송을 진행한다.
    위와 같이 컨트롤러는 client로부터 http request(전송 요청) 을 받았을 때 해당 요청에 맞는 라우트를 찾아서 그 라우트에 해당하는 로직을 수행하고, 그에 따라 나온 결과물을 전달하는 역할을 해준다고 할 수 있다. 특정 컨트롤러는 1개 이상의 라우트를 가지고 있고, 그 각각의 라우트는 각각 다른 기능을 한다.
import { Controller, Get } from '@nestjs/common';

@Controller('cats')
export class CatsController {
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}

그리고 위와 같이 컨트롤러는 Controller()라는 데코레이터를 통해 컨트롤러 기능을 추가해줌으로써 사용한다. @Controller() 안에 'cats'라는 파라미터는 해당 컨트롤러에 접근하기 위한 endpoint라고 할 수 있다. 그래서 이 CatsController 클래스 안에는 findAll이라는 GET 메서드를 사용한 http 요청을 처리하는 부분이 있는데, 이 findAll을 사용하려면 '/cats' 라우트로 요청을 보내되 HTTP의 GET 메서드를 사용해야 한다. 그래서 findAll위에는 Get() 데코레이터를 써줬다. GET, POST, PUT, PATCH, DELETE 등의 메서드들은 모두 이렇게 데코레이터로 표현할 수 있 도록 해놨다. 이 때, endpoint의 접두사가 cats라고 하면, Get('all') 이런식으로 해준다고 했을 때, 'cats/all' 로 endpoint를 변경할 수 있다.

Controller의 response

  • 본래 nestJS에서 기본으로(standard) 제공하는 response가 있다(권장사항). 이걸 썼을 때 원시 타입의 response를 주면 serialize 하지 않고 리턴하지만, object or array 형태로 주면 json 형태로 자동으로 serialize한다(+ status code도 기본으로 성공시 200을 주고, POST는 201을 준다). 이러한 기본 로직은 @HttpCode() 데코레이터로 수정할 수 있다.
  • response에서 status code를 커스텀하려면 @HttpCode 데코레이터를 사용하자.
  • 원시타입으로 return 값을 주면 text/html 타입의 데이터가 브라우저에서 렌더링된다. 하지만 object 타입으로 주면 application/json 형태로 온다(아까 말했듯이 자동으로 serialize 돼서 온다).
  • response를 규격화할 수 있는 데코레이터나 미들웨어 등을 알아봐야할듯. status code의 키나 post의 response body의 키 등을 통합해야 fe 쪽에서 데이터를 받을 때 똑같이 규격화해서 쓸 수 있음.
  • 위에서 말한건 standard이고, library로도 할 수 있다고 한다. 예를 들어, 기존의 express에서 쓰던 response.status(200).send() 형태로 쓰려면 @res를 쓰면된다. 하지만 앞서 말했듯이 권장 사항은 standard를 쓰는 것이다.

결론적으로 controller의 reponse에서는 statusCode와 필요하다면 return value 등을 넣어줘서 request에 따른 적당한 response를 준다. 이 때, @HttpCode 데코레이터를 적절히 쓰면 좋을 것 같고, return 값의 타입을 적절히 규격화해 만들어서 사용해야할 것 같다. 그래야 FE 쪽에서 예를 들어, axios.create로 만든 모듈에서 response를 받아서 처리하는 부분까지 공통화를 한다고 할 때도 수월하게 규격화된 형태로 할 수 있다.

Request Object

: 앞서 response에 대해서 알아봤는데, 이번엔 request 에 대해서 알아보자. controller에서 작업을 하다보면 클라이언트 쪽에서 보낸 request object를 살펴봐야할 일이 생긴다. Authorization 값을 확인한다거나(JWT Token 등을 쓴다 했을 때) 등의 일이 그에 해당한다. 이 때 @nestjs/common에서 기본으로 제공하는 Req를 쓰면된다.

@Request(), @Req() req
@Response(), @Res()* res
@Next() next
@Session() req.session
@Param(key?: string) req.params / req.params[key]
@Body(key?: string) req.body / req.body[key]
@Query(key?: string) req.query / req.query[key]
@Headers(name?: string) req.headers / req.headers[name]
@Ip() req.ip
@HostParam() req.hosts

위와 같은 Request object를 받아올 수 있다(http request 속의 프로퍼티라고 생각하면 된다.

** @Param은 users/yongki 에서 yongki라는 값을 받을 수 있는 것이고

@Get('/:user_name')
getUserInformByName(@Params('user_name') userName){
	return this.userService.getUserInformByName(userName);
}

위와 같이 쓰면된다.

중간에 다른 얘기긴하지만, 대략적으로 위와 같은 response, request Header의 정보들과 general의 정보들을 통제 및 조회하는 곳이 controller이다.

** Redirect 를 쓰면 브라우저단에서 자동으로 캐싱을 한다

profile
완벽함 보다는 최선의 결과를 위해 끊임없이 노력하는 개발자

0개의 댓글