NestJS의 기본 개념(1)

23096 단어 NestJSNestJS

컨트롤러

  • 요청을 받는 관문역할을 함
  • MVC패턴에서 말하는 컨트롤러의 역할
  • 들어오는 요청을 받고, 처리된 결과를 응답해주는 역할.
  • 운영중인 어플이 수행해야 하는 특정 요청을 받는 것이 목적
  • 정해진 요청들을 분류하는 라우팅 메커니즘을 통해 각 컨트롤러가 받을 수 있는 요청을 분류함.
  • 이를 통해 컨트롤러를 목적에 따라 구분할수 있어 구조적이고 모듈화된 소프트웨어를 작성할 수 있음.

1. 컨트롤러 생성

  • 컨트롤러 생성 nest-cli 명령어
$ nest g contrller [name]
# or
$ nest g co [name]
  • nest-cli 명령어
  • 컨트롤러 및 보일러 플레이트 코드를 할번에 생성할 수 있는 명령어
$ nest g resource [name]
# or
$ nest g res [name]

2. 라우팅

  • 기본적인 소스 코드
// app.controller.ts
import {Controller, Get} from "@nestjs/common";
import {AppService} from './app.service';

@Controller()
export class AppController {
  consructor(private readonly appService: AppService) {}
  
  @Get()
  getHello(): string {
    return tshi.appService.getHello();
  }
}
  • 스프링 프레임워크와 비슷한 구조. Nest에서 데코레이터라고 부르고, 스프링에선 어노테이션이라고 부름
  • 기본적으로 @Get, @Post 등의 RestAPI는 루트 경로로 들어오는 요청을 처리할 수 있게 되며, '/'는 생략처리됨.

3. 와일드카드

  • 라우팅 패스는 와일드 카드를 이용하여 작성할 수 있음.
    • 라우팅 패스란 라우팅 경로가 비슷한 문자열 요청이 들어오면 그 비슷한 문자열의 컨트롤러로 요청이 감.
  • 예를 들어 * 문자를 사용하면 문자열 가운데 어떤 문자가 와도 상관없이 라우팅 패스를 구성하겠다는 뜻
  • 소스코드
@Get("he*lo")
getHello(): string {
  return this.appService.getHello();
}
  • *외엔 ?,+,()는 와일드카드로 동일하게 동작하지만, -, .은 문자열로 취급함

4. 요청 객체(Request Object)

  • 클라이언트 어떤 요청을 보내면서 종종 서버가 원하는 정보를 함께 전송함.
  • Nest는 요청과 함께 전달되는 데이터를 핸들러가 다룰 수 있는 객체로 변환함.
  • 이렇게 변환된 객체 @Req() 데코레이터를 이용하여 다룰 수 있음.
  • 소스코드
import {Request} from "express";
import {Controller, Get, Req} from "@nestjs/common";
import {AppService} from "./app.service";

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}
  
  @Get()
  getHello(@Req() req: Request): string {
    console.log(req);
    return this.appService.getHello();
  }
}
  • 요청 객체는 HTTP요청을 나타냄
  • 쿼리 스트링, 파라미터, 헤더와 바디 정보를 가지고 있음
  • Nest에선 요청객체를 직접 다루기보단 @Query, @Param(key?: string), @Body의 데코레이터를 이용하여 요청을 처리함.

5. 응담

  • 위에서 resource 커맨드를 통해 Users리소스에 대한 Rest API를 만들었고, 서버를 실행하면 로그에 어떤 라우팅 패스를 통해 요청을 받을 수 있는지 확인할 수 있음.
  • 소스코드
import { Controller, Get, Post, Body, Patch, Param, Delete, Res, Httpcode } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('users')
export class UsersController {
  constructor(private readonly usersService: UsersService) {}

  @Post()
  create(@Body() createUserDto: CreateUserDto) {
    return this.usersService.create(createUserDto);
  }

  @Get()
  findAll(@Res() res) {
    cosnt users = this.usersService.findAll();
    return res.status(200).send(users);	
  }

  @Get(':id')
  findOne(@Param('id') id: string) {
    if(+id<1) {
      throw new NotFoundException("User is not found");
    }
    return this.usersService.findOne(+id);
  }
  /*
  'users/:id'요청결과
  {
    "statusCode": 404,
    "message": "User is not found",
    "error": "Not Found"
  }
  */
  @HttpCode(202)
  @Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.usersService.update(+id, updateUserDto);
  }
  /*
  202코드는 요청이 접수됐으나, 아직 해당 요청에 대해 처리중이거나 처리 시작전임을 의미
  */
  @Delete(':id')
  remove(@Param('id') id: string) {
    return this.usersService.remove(+id);
  }
}

6. 헤더

  • Nest는 응답 헤더 역시 자동 구성해줌.
  • 만약 응답을 받는 서버 또는 클라이언트와 약속된 커스텀 헤더를 추가하고 싶다면 @Header 데코레이터를 사용하면 됨
  • 인자로 헤더 이름과 값을 받음
  • 라이브러리에서 제공하는 응답객체를 사용해서 res.header()로 직접 설정도 가능
  • 소스코드
import {Header} from "@nestjs/common";

@Header("Custom", "Test Header")
@Get(":id")
findOneWithHeader(@Param("id") id: string) {
  return this.usersService.findOne(+id);
}
  • 위의 코드로 응답을 받으면 headers부분에 키와 값으로 Custom: Test Header가 들어가 있는 걸 확인할 수 있음.
  • curl로 api 확인해보기
$ curl http://localhost:3000/users/1 -v
# -X옵션을 생략하고 -v 옵션을 주면 Get으로 동작함.

7. 리디렉션

  • 종종 서버는 요청을 처리한 후 요청을 보낸 클라이언트를 다른 페이지로 이동시키고 싶은 경우가 있음.
  • 응답바디에 redirectUrl을 포함시켜 클라이언트가 스스로 페이지를 이동해도 되지만, @Redirect 데코레이터를 사용하면 쉽게 구현 가능.
  • 첫번째 인자는 url, 두번째 인자는 상태코드 임
  • 다른 상태코드로 바꾸어 응답할 수 있도록 되어 있음
  • 하지만 301,307,308과 같이 리다이렉트로 정해진 응답코드가 아닐 경우 브라우저가 제대로 반응하지 않을 수 있음.
  • 소스코드
import {Redirect} from "@nestjs/common";

@Redirect("https://nestjs.com", 301)
@Get(":id")
findOne(@Param("id") id: string) {
  return this.usersService.findOne(+id);
}
  • 만약 상태에 따라 동적으로 리디렉트 하고자 한다면 응답으로 다음 객체를 리턴하면 됨.
{
  "url": string,
  "statusCode": number
}
  • 소스코드
// app.controller.ts
@Get("redirect/docs")
@Redirect("https://docs.nestjs.com", 302)
getDocs(@Query("version") version: string) {
  if(version && version === '5') {
    return {url: "https://docs.nestjs.com/v5/"}
  }
}

8. 라우트 파라미터

좋은 웹페이지 즐겨찾기