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';
}