lottie
Seungjun's blog
blog
nestjs docs 2편

Request object

  핸들러는 종종 클라이언트측 request object의 세부사항들에 대해 접근해야한다. Nest는 @Req() 데코레이터를 이용하여 request object에 접급할 수 있도록 한다.

// cats.controller.ts
import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';
@Controller('cats')
export class CatsController {
  @Get()
  findAll(@Req() request: Request): string {
    return 'This action returns all cats';
  }
}

 아래는 Nest가 제공하는 데코레이터들이다. Nest에서는 기존의 방식이 아닌 데코레이터를 통해 request object에 접근해야 한다.

데코레이터

기존

@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

@Res() 또는 @Response() 를 사용하면 직접 요청객체에 접근할 수 있다. 하지만 이 경우 직렬화를 알아서 처리해야하는 이슈가 발생한다.

Resources

// cats.controller.ts
import { Controller, Get, Post } from '@nestjs/common';
@Controller('cats')
export class CatsController {
  @Post()
  create(): string {
    return 'This action adds a new cat';
  }
  @Get()
  findAll(): string {
    return 'This action returns all cats';
  }
}

  Nest는 표준 HTTP 에 대한 모든 데코레이터를 제공한다.

methods: 

@Get()@Post()@Put()@Delete()@Patch()@Options(), @Head(), @All() (defines an endpoint that handles all of them)


Route wildcards

  패턴에 기반한 라우트도 사용가능하다. *(asterisk ) 를 와일드 카드로 사용한다. *이 위치한 자리에 어떠한 글자가 오더라도 정상적인 라우트로 작동한다.

@Get('ab*cd')
findAll() {
  return 'This route uses a wildcard';
}

  이 기호들은 라우팅 경로로 사용할 수 있으며 해당 정규표현식의 하위 요소이다. -.은 문자 그대로 string으로 사용되어진다.


Status code

 앞서 말했듯이 응답 상태 코드는 POST 요청이 201인 경우가 아니라면 200이 기본값이다. 우리는 이를 손쉽게 핸들러 단계에서 @HttpCode(...) 데코레이터를 이용해 변경할 수 있다.

@Post()
@HttpCode(204)
create() {
  return 'This action adds a new cat';
}

 상태코드가 동적인 경우 @Res() 데코레이터를 사용해 적절한 응답으로 처리해 준다.


Headers

 @Header() 데코레이터를 사용하여 적절한 응답헤더로 변경할 수 있다.

@Post()
@Header('Cache-Control', 'none')
create() {
  return 'This action adds a new cat';
}


Redirection

 @Redirect() 데코레이터는 url 과statusCode 를 인자로 받으며 이는 모두 선택 사항이다. statusCode 의  기본값은302 (Found) 이다.

@Get()
@Redirect('https://nestjs.com', 301)

 동적인 HTTP 상태 코드 또는 리다이렉트 URL을 사용하기 위해 아래의 형태로 라우트 핸들러 메소드 단계에서 반환한다.

{
  "url": string,
  "statusCode": number
}

 반환되는 값은 @Redirect() decorator를 지나며 오버라이드 될 것이다.

예시

@Get('docs')
@Redirect('https://docs.nestjs.com', 302)
getDocs(@Query('version') version) {
  if (version && version === '5') {
    return { url: 'https://docs.nestjs.com/v5/' };
  }
}


Route parameters

  정적 라우트는 request의 일부로 동적 데이터를GET /cats/1 수락해야 하는 경우(예: id 가 1인 cat get요청) 정상 작동하지 않는다. 매개변수로 라우트를 정의하기 위해, 경로 매개변수 토큰을 추가하여 요청 URL의 해당 위치에서 동적 값을 가져올 수 있다. 아래 코드에서 매개변수 토큰의 사용법을 보여준다.

@Get(':id')
findOne(@Param() params: any): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}

 @Param()메서드는 매개 변수를 사용할 수 있도록 합니다. 위의 코드에서 볼 수 있듯이 를 id참조하여 매개변수에 액세스할 수 있습니다 . 특정 매개 변수를 데코레이터에 전달한 다음 메서드에서 이름으로 매개 변수를 직접 참조할 수도 있다.

@Get(':id')
findOne(@Param('id') id: string): string {
  return `This action returns a #${id} cat`;
}


Sub-Domain Routing

 @Controller데코레이터는 요청의 HTTP 호스트가 특정 값과 일치하도록 요구하는 옵션을 사용할 수 있다

@Controller({ host: 'admin.example.com' })
export class AdminController {
  @Get()
  index(): string {
    return 'Admin page';
  }
}

 라우트의 path와 유사한  hosts옵션은 토큰을 사용하여 호스트 이름의 해당 위치에서 동적 값을 가져올 수 있다.  이러한 방식으로 선언된 호스트 매개변수는 메소드 서명에 추가되어야 하는 @HostParam()데코레이터를 사용하여 접근할 수 있다 .

@Controller({ host: ':account.example.com' })
export class AccountController {
  @Get()
  getInfo(@HostParam('account') account: string) {
    return account;
  }
}


Request payloads

 @Body() 데코레이터를 사용하는 경우 우선 DTO (Data Transfer Object) 스키마를 결정해야 합니다 .


 DTO는 데이터가 네트워크를 통해 전송되는 방법을 정의하는 객체입니다. TypeScript 인터페이스나 간단한 클래스를 사용하여 DTO 스키마를 결정할 수 있습니다 . DTO (Data Transfer Object)에서는 클래스를 사용하는 것이 권장됩니다 . 

 클래스는 컴파일된 JavaScript에서 실제 엔터티로 보존되지만 TypeScript 인터페이스는 자바스크립트로 컴파일 중에 제거되기 때문에 Nest는 런타임에 이를 참조할 수 없습니다. 이는 파이프 와 같은 기능이 런타임 시 변수의 메타 유형에 접근할 때 추가적인 가능성을 허용하기 때문이다.

//create-cat.dto.ts
export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}
// cats.controller.ts
import CreateCatDto from '@/create-cat.dto.ts'
@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}