728x90
반응형

 

전 글에서 movieData DTO를 만들어봤다.

이번 글에선 updateData DTO를 만들어보겠다.

 

먼저 update-movie.dto.ts 파일을 만든다.

 

update-movie.dto.ts

import {IsString, IsNumber} from 'class-validator'

export class CreateMovieDto {
    @IsString()
    readonly title?: string;

    @IsNumber()
    readonly year?: number;
    
    @IsString({each:true})
    readonly genres?: string[];
}

 

movieData의 DTO와 다른 점은 물음표가 있다는 점인데, 이는 필수사항은 아니게 한다는 뜻이다.

 

그다음 Controller와 Service에 추가하는 방법까지는 똑같다.

여기서 우리는 부분 객체라는 것을 써볼 것이다. 먼저 아래와 같이 설치해준다.

$npm i @nextjs/mapped-types

 

 

그다음 PartialType을 사용하기 위해 코드를 바꿔준다.

import {IsString, IsNumber} from 'class-validator'
import { PartialType } from '@nestjs/mapped-types';
import { CreateMovieDto } from './create-movie.dto';

export class UpdateMovieDto extends PartialType(CreateMovieDto) {}

 

 

이런식으로 CreateMovieDto를 상속할 수 있게 만들 수 있다. 또한 각각의 요소가 필수사항이 아니게끔 만들어준다.

 

이렇게 하고 POST 메소드로 Create하고 PATCH로 업데이트를 실행해보면 성공!

728x90
반응형
728x90
반응형

 

updateData랑 movieData한테 타입을 부여하기 위해서 우리는 DTO(Data Transfer Object, 데이터 전송 객체)를 만들어야한다. 먼저 create-movie.dto.ts 파일을 만들자.

 

 

create-movie.dto.ts

export class CreateMovieDto {
    readonly title: string;
    readonly year: number;
    readonly genres: string[];
}

 

 

그 다음 Controller 부분과 Service 부분에 타입을 추가해주자. (movieData)

 

Controller

    @Post()
    create(@Body() movieData : CreateMovieDto) {
        return this.moviesService.create(movieData);
    }

 

Service

    create(movieData:CreateMovieDto) {
        this.movies.push({
            id: this.movies.length + 1,
            ...movieData
        })
        return true;
    }

 

이렇게 해두면 아래와 같이 movieData. 만 입력해도 클래스가 가진 속성들이 자동으로 나와서 코딩하기에도 편리하다.

또한 타입에 대한 유효성을 검사할 수도 있다.

 

클래스의 유효성 검사를 위해 main.ts에 다음과같이 pipe를 만들어주겠다.

 

main.ts

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(
    new ValidationPipe()
  )
  await app.listen(3000);
}
bootstrap();

 

 

또한 아래 명령어를 입력해서  npm 모듈을 설치하자.

$npm i class-validator class-transformer

 

그다음 아까 만들어두었던 dto파일에 다음과같이 데코레이터를 추가하자.

 

create-movie.dto.ts

import {IsString, IsNumber} from 'class-validator'

export class CreateMovieDto {
    @IsString()
    readonly title: string;

    @IsNumber()
    readonly year: number;
    
    @IsString({each:true})
    readonly genres: string[];
}

 

 

 

그 다음 postman에서 다음과 같이 POST 메소드로 {hacked: "by me"} 라는  body를 요청해보면 이런 결과창이 뜬다.

 

ValidationPipe 와 CreateMovieDto를 사용하고 있기 때문에 DTO의 타입을 실시간으로 확인할 수 있는 것이다.

 

ValidationPipe의 옵션 중 유용한 옵션인 whitelist라는 것이 있는데,

true로 설정하면 아무 Decoreator도 없는 어떠한 property의 object를 거룰 수 있다.

 

또한 보안을 위해 forbidNonWhitelisted 라는 옵션도 있다. 

이는 정의를 하지 않은 데이터가 error메세지에 뜨게끔 도와준다

 

transform라는 옵션은

보통 데이터를 body로 받을 때 string으로 받아서 정수형은 parseInt를 써야 했지만,

그럴 필요 없이 바로 원하는 자료형으로 바꿔주는 기능을 한다.

 

 

여기까지 추가를 해보면

 

 

main.ts

import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(
    new ValidationPipe({
      whitelist : true, 
      forbidNonWhitelisted : true,
      transform : true
    })
  )
  await app.listen(3000);
}
bootstrap();

 

 

이렇게 되고, 추가했었던 parseInt를 바꿔주면 된다.

 

movies.controller.ts

import { Controller, Get, Param, Post, Delete, Patch, Body, Query } from '@nestjs/common';
import { CreateMovieDto } from './dto/create-movie.dto';
import { Movie } from './entities/movie.entity';
import { MoviesService } from './movies.service';

@Controller('movies')
export class MoviesController {
    constructor(private readonly moviesService: MoviesService) {}

    @Get()
    getAll(): Movie[] {
        return this.moviesService.getAll();
    }

    @Get('/:id')
    getOne(@Param('id') movieId: number){
        return this.moviesService.getOne(movieId)
    }

    @Post()
    create(@Body() movieData : CreateMovieDto) {
        return this.moviesService.create(movieData);
    }

    @Delete('/:id')
    remove(@Param('id') movieId:number) {
        return this.moviesService.deleteOne(movieId);
    }

    @Patch('/:id')
    patch(@Param('id') movieId:number, @Body() updateData) {
        return this.moviesService.update(movieId,updateData)
    }
}

 

 

movies.service.ts

import { Injectable, NotFoundException } from '@nestjs/common';
import { NotFoundError } from 'rxjs';
import { CreateMovieDto } from './dto/create-movie.dto';
import { Movie } from './entities/movie.entity';

@Injectable()
export class MoviesService {
    private movies: Movie[] = [];

    getAll(): Movie[] {
        return this.movies;
    }

    getOne(id:number): Movie {
        
        const movie = this.movies.find(movie => movie.id === id);
        if(!movie) {
            throw new NotFoundException(" ID가 존재하지 않습니다. ")
        }

        return movie;

    } 

    deleteOne(id:number) {
        this.getOne(id)
        this.movies = this.movies.filter(movie => movie.id !== id)
    }

    create(movieData:CreateMovieDto) {
        this.movies.push({
            id: this.movies.length + 1,
            ...movieData
        })
        return true;
    }

    update(id: number, updateData) {
        const movie = this.getOne(id);
        this.deleteOne(id)
        this.movies.push({ ...movie, ...updateData})
    }

}

 

728x90
반응형
728x90
반응형

 

우리가 만약 getOne으로 데이터를 찾고자 하는데 실수로 입력을 했다고 치면 데이터가 없는지, 어떤 오류가 있는지 에러 핸들링을 해주어야 한다.

 

movies.service.ts

    getOne(id:string): Movie {
        
        const movie = this.movies.find(movie => movie.id === parseInt(id));
        if(!movie) {
            throw new NotFoundException(" ID가 존재하지 않습니다. ")
        }

        return movie;

    }

 

이런 식으로  getOne부분에 movie가 존재하지 않을 경우 error를 내보내도록 했다.

실제로 postman에서 request를 보내보면

 

 

이런식으로 에러가 뜨는 것을 확인할 수 있다.

 

방금 만든 getOne() 함수로 우리가 데이터를 삭제할 때 해당 Id를 가지고 있는 Movie가 존재하는지 먼저 확인해 볼 수 있고 에러 처리를 할 수도 있다. 때문에 코드가 더 깔끔해진다.

 

    deleteOne(id:string) {
        this.getOne(id)
        this.movies = this.movies.filter(movie => movie.id !== parseInt(id))
    }

 

 

이번엔 update service를 만들어보자. 먼저, Controller 부분을 바꿔주자.

    @Patch('/:id')
    patch(@Param('id') movieId:string, @Body() updateData) {
        return this.moviesService.update(movieId,updateData)
    }

 

 

아직 Service부분에서 update 함수를 선언하지 않았기 때문에 당연히 에러가 뜬다. Service부분을 보자.

 

movies.service.ts

import { Injectable, NotFoundException } from '@nestjs/common';
import { NotFoundError } from 'rxjs';
import { Movie } from './entities/movie.entity';

@Injectable()
export class MoviesService {
    private movies: Movie[] = [];

    getAll(): Movie[] {
        return this.movies;
    }

    getOne(id:string): Movie {
        
        const movie = this.movies.find(movie => movie.id === parseInt(id));
        if(!movie) {
            throw new NotFoundException(" ID가 존재하지 않습니다. ")
        }

        return movie;

    } 

    deleteOne(id:string) {
        this.getOne(id)
        this.movies = this.movies.filter(movie => movie.id !== parseInt(id))
    }

    create(movieData) {
        this.movies.push({
            id: this.movies.length + 1,
            ...movieData
        })
        return true;
    }

    update(id: string, updateData) {
        const movie = this.getOne(id);
        this.deleteOne(id)
        this.movies.push({ ...movie, ...updateData})
    }

}

 

 

postman에서 실행해보면 정상작동하는것을 확인할 수 있다.

728x90
반응형
728x90
반응형

REST API를 개발할 때, 여러 메소드로 실험을 해보는것이 좋다.

그러기 위해 있는 좋은 프로그램이 postman이라는 프로그램이다.

 

먼저 사이트에서 다운을 받는다.

https://www.postman.com/downloads/

 

Download Postman | Get Started for Free

Try Postman for free! Join 17 million developers who rely on Postman, the collaboration platform for API development. Create better APIs—faster.

www.postman.com

 

 

 

그 다음 계정을 생성한다.

 

 

 

My Workspace에 들어간다.

 

 

 

우측 상단에 New를 클릭한다.

 

 

 

HTTP Request를 클릭한다.

 

원하는 URL을 추가해주고 동작을 할 수 있다.

 

 

728x90
반응형
728x90
반응형

Service는 movie의 로직을 관리하는 역할을 맡을 것이다. Controller가 URL을 받아오면, 원하는 비즈니스 로직을

실행해준다. ( DB 작업 등이 이곳에서 이루어질 것이다. )

 

먼저 Controller를 만들었던것과 같이 Service를 만들어보자.

nest g s

 

그럼, 이름을 입력하라고 하는데, Controller와 같은 movies로 만들어보겠다.

 

이렇게 실행을 해주면!

 

 

 

위와 같이 자동으로 파일들이 생성되고, 루트 모듈에서 선언되는것을 확인 할 수 있다. ( 매우 편리한 기능! )

위에서 말했듯이 Service에선 주로 DB작업등과 같은 로직을 실행하는데, 이 강의에서는 실제DB를 다루는 것은 하진 않는다. 내 블로그에 있는 MongoDB 파트를 완벽히 이해하면 충분히 할 수 있을 것이다.

 

 

먼저, src 폴더 아래 다음과 같이 파일을 생성해준다.

 

 

그 다음 Movie class를 만들어준다.

 

movie.entity.ts

export class Movie {
    id: number;
    title: string;
    year: number;
    genres: string[];
}

 

 

이 class를 Service 파일에서 가져온다.

 

movie.service.ts

import { Injectable } from '@nestjs/common';
import { Movie } from './entities/movie.entity';

@Injectable()
export class MoviesService {
    private movies: Movie[] = [];
}

 

그 다음  Controller에서 쓸 함수를 정의한다. 이 때 이름은 중복되어도 상관이 없다.

 

movie.service.ts

import { Injectable } from '@nestjs/common';
import { Movie } from './entities/movie.entity';

@Injectable()
export class MoviesService {
    private movies: Movie[] = [];

    getAll(): Movie[] {
        return this.movies;
    }

    getOne(id:string): Movie {
        return this.movies.find(movie => movie.id === parseInt(id));
    } 
}

 

DB에 접근해서 모든 Movie를 조회하는 함수와 id를 통해 Movie 한개를 조회하는 함수를 작성했다.

 

 

이번엔 Controller에서 방금 만들었던 Service를 사용해보자. express.js처럼 수도으로 import하는 방법은 Nest.js에서 기본적으로 쓰는 방법이 아니다. 우리가 요청을 해야한다.

 

먼저 class에 구조체(constructor)를 가져오고, getAll() 부분과 getOne() 부분을 바꿔보겠다.

 

import { Controller, Get, Param, Post, Delete, Patch, Body, Query } from '@nestjs/common';
import { Movie } from './entities/movie.entity';
import { MoviesService } from './movies.service';

@Controller('movies')
export class MoviesController {
    constructor(private readonly moviesService: MoviesService) {}

    @Get()
    getAll(): Movie[] {
        return this.moviesService.getAll();
    }

    @Get('search') 
    search(@Query('year') searchingYear : string) {
        return `${searchingYear} 이라는 데이터를 찾을 것입니다.`
    }

    @Get('/:id')
    getOne(@Param('id') movieId: string){
        return this.moviesService.getOne(movieId)
    }

    @Post()
    create(@Body() movieData : Object) {
        return movieData;
    }

    @Delete('/:id')
    remove(@Param('id') movieId:string) {
        return `${movieId} id를 가진 movie를 삭제합니다.`;
    }

    @Patch('/:id')
    patch(@Param('id') movieId:string, @Body() updateData) {
        return {
            updatedMovie : movieId,
            ...updateData
        }
    }
}

 

 

이번엔 Service에서 delete함수와 create함수를 만들어보겠다.

 

movies.service.ts

import { Injectable } from '@nestjs/common';
import { Movie } from './entities/movie.entity';

@Injectable()
export class MoviesService {
    private movies: Movie[] = [];

    getAll(): Movie[] {
        return this.movies;
    }

    getOne(id:string): Movie {
        return this.movies.find(movie => movie.id === parseInt(id));
    } 

    deleteOne(id:string): boolean {
        this.movies.filter(movie => movie.id !== parseInt(id))
        return true;
    }

    create(movieData) {
        this.movies.push({
            id: this.movies.length + 1,
            ...movieData
        })
        return true;
    }
}

 

그리고 Controller 부분을 바꿔주자. search부분은 이미 설명을 했으니 삭제하겠다.

 

movies.controller.ts

import { Controller, Get, Param, Post, Delete, Patch, Body, Query } from '@nestjs/common';
import { Movie } from './entities/movie.entity';
import { MoviesService } from './movies.service';

@Controller('movies')
export class MoviesController {
    constructor(private readonly moviesService: MoviesService) {}

    @Get()
    getAll(): Movie[] {
        return this.moviesService.getAll();
    }

    @Get('/:id')
    getOne(@Param('id') movieId: string){
        return this.moviesService.getOne(movieId)
    }

    @Post()
    create(@Body() movieData : Object) {
        return this.moviesService.create(movieData);
    }

    @Delete('/:id')
    remove(@Param('id') movieId:string) {
        return this.moviesService.deleteOne(movieId);
    }

    @Patch('/:id')
    patch(@Param('id') movieId:string, @Body() updateData) {
        return {
            updatedMovie : movieId,
            ...updateData
        }
    }
}

 

 

동작은 postman에서 확인할 수 있다.

 

 

 

 

 

참조

https://nomadcoders.co/nestjs-fundamentals/lectures/1947

 

All Courses – 노마드 코더 Nomad Coders

초급부터 고급까지! 니꼬쌤과 함께 풀스택으로 성장하세요!

nomadcoders.co

 

728x90
반응형

'Back-End > Nest.js' 카테고리의 다른 글

Nest.js | REST API | DTOs and Validation(1)  (0) 2021.09.29
Nest.js | REST API | Movies Service(2)  (0) 2021.09.29
Nest.js | REST API | More Routes  (0) 2021.09.28
Nest.js | REST API | Movies Controller  (0) 2021.09.24
Nest.js | 개요 | Modules  (0) 2021.09.24
728x90
반응형

 

우리가 클라이언트에서 어떤 데이터를 원할 때는 백엔드에 요청을 해야된다.

 

예를들어 백엔드에서 POST 메소드로 josn body를 요청받아 movie를 create하고 싶다면,

 

    @Post()
    create(@Body() movieData : Object) {
        return movieData;
    }

 

이런식으로 해당 부분을 바꿔주면 된다.

 

 

또한 PATCH 메소드를 통해 update를 하고 싶다면,

    @Patch('/:id')
    patch(@Param('id') movieId:String, @Body() updateData) {
        return {
            updatedMovie : movieId,
            ...updateData
        }
    }

이런식으로 Patch로 받은 데이터를 추가하고 반환할 수 있다.

 

node.js로 json데이터를 주고 받을 때는 따로 설정을 해야될 것들이 있었지만, Nest.js는 이러한 과정을

아주 편리하게 이용할 수 있도록 해준다.

 

 

우리가 Movie에 대해 year이라는 속성으로 데이터를 찾고자 할 때는

    @Get('/:id')
    getOne(@Param('id') movieId: String){
        return `id is ${movieId}`;
    }

    @Get('search') 
    search(@Query('year') searchingYear : string) {
        return `${searchingYear} 이라는 데이터를 찾을 것입니다.`
    }

 

이런식으로 사용할 수 있다. 하지만  위와 같이 /:id를 param으로 갖는 곳 하단에 선언을 해주고, 실행을 해보면

이런 식으로 search를 id로 인식하여 원하는 값을 얻지 못하게 된다. 따라서 GET /:id 상단에 선언을 해야 된다.

 

    @Get('search') 
    search(@Query('year') searchingYear : string) {
        return `${searchingYear} 이라는 데이터를 찾을 것입니다.`
    }

    @Get('/:id')
    getOne(@Param('id') movieId: String){
        return `id is ${movieId}`;
    }

 

이렇게 만들고 다시 실행을 해보면

 

이런 식으로 우리가 원하는 값을 얻을 수 있게 된다.

 

 

참조

https://nomadcoders.co/nestjs-fundamentals/lectures/1946

 

All Courses – 노마드 코더 Nomad Coders

초급부터 고급까지! 니꼬쌤과 함께 풀스택으로 성장하세요!

nomadcoders.co

 

728x90
반응형

'Back-End > Nest.js' 카테고리의 다른 글

Nest.js | REST API | Movies Service(2)  (0) 2021.09.29
Nest.js | REST API | Movies Service(1)  (0) 2021.09.28
Nest.js | REST API | Movies Controller  (0) 2021.09.24
Nest.js | 개요 | Modules  (0) 2021.09.24
Nest.js | 개요 | Service  (0) 2021.09.24
728x90
반응형

참조 ( 제가 존경하는 노마드 코더님의 강의영상 )

https://nomadcoders.co/nestjs-fundamentals/lectures/1945

 

All Courses – 노마드 코더 Nomad Coders

초급부터 고급까지! 니꼬쌤과 함께 풀스택으로 성장하세요!

nomadcoders.co

 

 

먼저 완전 아무것도 없는 상태로 시작을 해보겠다.

 


 

Nest.js 에서는 generate라는 훌륭한 명령어가 있다.

커맨드 라인에 관하여 상당히 편리하게 되어있기 때문에 우리는 거의 모든 걸 편리하게 생성할 수 있다.

 

$ nest

이 명령어를 치면 우리가 사용할 수 있는 명령어들이 나타난다.

 

그 중 generate 옵션을 살펴보면,

 

이런식으로 콘솔에 나타난다. controller를 생성해보자.

 

$ nest g co

 

 

Controller의 이름을 어떻게 사용할건지에 대해 물어본다.

 

 

movies라고 입력하면 

 

import { Module } from '@nestjs/common';
import { MoviesController } from './movies/movies.controller';

@Module({
  imports: [],
  controllers: [MoviesController],
  providers: [],
})
export class AppModule {}

 

자동으로 movies라는 폴더가 생성되고, 루트 모듈 파일에 자동으로 Moviescontroller가 생성되는걸 확인할 수 있다

 

 

movies.controller.ts

 

import { Controller, Get } from '@nestjs/common';

@Controller('movies')
export class MoviesController {

    @Get()
    getAll(){
        return 'hello movies'
    }
}

 

movies.controller.ts 파일을 고치고 npm run start를 실행해보면..!

 

 

이렇게 에러메세지가 뜬다.. 왜그럴까?

 

 

기본적인 Controller 데코레이터에서는 비어있지만, 명령어로 만든 Controller는 이와같이 안에 문자열이

생성된 채로 만들어진다. 때문에 마지막 ip주소 마지막 부분에 /movies를 붙이면

 

이렇게 잘 뜨는 것을 확인 할 수 있을것이다.

 

 

이번에는 파라미터를 가지는 GET메소드를 구현해보자!

 

movies.controller.ts

import { Controller, Get } from '@nestjs/common';

@Controller('movies')
export class MoviesController {

    @Get()
    getAll(){
        return 'hello movies'
    }

    @Get('/:id')
    getOne(){
        return 'hello one movie'
    }
}

 

/:id에 값이 들어올 경우 정상적으로 뜨는 것을 확인할 수 있다. (ex localhost:3000/movies/1)

 

 

또한 다음과 같이 파라미터의 자료형을 지정하고 자유자재로 쓸 수도 있다.

 

movies.controller.ts

import { Controller, Get, Param } from '@nestjs/common';

@Controller('movies')
export class MoviesController {

    @Get()
    getAll(){
        return 'hello movies'
    }

    @Get('/:id')
    getOne(@Param('id') movieid: String){
        return `id is ${movieid}`
    }
}

 

 

자 그럼 이번엔 다른 메소드들도 사용해서 controller의 틀을 잡아보자.

 

movies.controller.ts

import { Controller, Get, Param, Post, Delete, Patch } from '@nestjs/common';

@Controller('movies')
export class MoviesController {

    @Get()
    getAll(){
        return 'hello movies';
    }

    @Get('/:id')
    getOne(@Param('id') movieId: String){
        return `id is ${movieId}`;
    }

    @Post()
    create() {
        return 'This will create a Movie';
    }

    @Delete('/:id')
    remove(@Param('id') movieId:String) {
        return `${movieId} id를 가진 movie를 삭제합니다.`
    }

    @Patch('/:id')
    patch(@Param('id') movieId:String) {
        return `${movieId} id를 가진 movie를 변경합니다.`
    }
}

 

 

여기까지 멋진 Controller를 만들어보았다.

728x90
반응형

'Back-End > Nest.js' 카테고리의 다른 글

Nest.js | REST API | Movies Service(1)  (0) 2021.09.28
Nest.js | REST API | More Routes  (0) 2021.09.28
Nest.js | 개요 | Modules  (0) 2021.09.24
Nest.js | 개요 | Service  (0) 2021.09.24
Nest.js | 개요 | Controller(2)  (0) 2021.09.24
728x90
반응형

일단 먼저 우리만의 모듈을 만들어보자. 이름은 cats라고 하겠다.

 

$ nest g module cats

루트 폴더에서 이 명령어를 실행해주면

 

 

이렇게 자동으로 폴더가 생성된다.

 

전체적인 파일 구조는 이런식이 될 것이다.

 

 

Feature Modules(기능 모듈)

 

먼저 cats.module.ts를 다음과 같이 수정해보자.

 

cat.module.ts

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}

이렇게 controllers와 provider를 가지는 모듈을 한 개 생성하였다. ( controller와 provider는 아직 생성 안 함.)

 

그 다음 app.module.ts(루트 모듈) 파일을 수정해주어야 한다.

 

app.module.ts

import { Module } from '@nestjs/common';
import { CatsModule } from './cats/cats.module';

@Module({
  imports: [CatsModule],
})
export class AppModule {}

여기까지가 기능 모듈의 기본적인 예이다. 모듈을 생성하고, 루트 모듈에 연결해주었다.

 

 

Shared Modules( 공유 모듈)

 

Nest에서의 모듈은 기본적으로 싱글톤이다. 여러 모듈간에 쉽게 프로바이더의 인스턴스를 공유할 수 있다.

 

공유를 하기 위해서 만들었던 모듈에 export 옵션을 만들어주어야한다.  여기서 모듈에서 사용하는 용어를 살펴보면,

Providers Nest 인젝터에 의해 인스턴스화 되고 적어도 이 모듈에서 공유될 수 있는 프로바이더
controllers 인스턴스화 되어야 하는 이 모듈에 정의된 컨트롤러 세트
imports 모듈에 필요한 프로바이더를 내보내는 가져온 모듈들
exports 다른모듈에서 import하여 사용되어야 하는 프로바이더의 하위 집합

 

이렇게 되어있다. export를 써보자.

 

cat.module.ts

import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService]
})
export class CatsModule {}

 

이렇게 하면 CatsModule을 가져오는 모든 모듈이 CatService에 액세스 할 수 있다.

( 가져올 때는 import를 써준다. )

 

 

 

Global modules

 

모든 곳에서 동일한 모듈 세트를 가져와야할 때 @Global() 데코레이터를 이용하여 전역 모듈을 생성할 수 있다.

 

import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';

@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}

 

이런식으로 exports 옵션에 넣어주면 CatService를 필요로 하는 모듈에서 가져와 쓸 수 있다.

Global 데코레이터는 일반적으로 루트 또는 코어 모듈에서 한번만 등록을 해야한다. 서비스를 가져오려는 모듈에서

가져오기 배열에서 CatModule을 가져올 필요가 없다.

728x90
반응형

'Back-End > Nest.js' 카테고리의 다른 글

Nest.js | REST API | More Routes  (0) 2021.09.28
Nest.js | REST API | Movies Controller  (0) 2021.09.24
Nest.js | 개요 | Service  (0) 2021.09.24
Nest.js | 개요 | Controller(2)  (0) 2021.09.24
Nest.js | 개요 | Controllers(1)  (0) 2021.09.24
728x90
반응형

소개에서 다루었던 파일들을 다시 한번 보자.

 

main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

이곳에서 async await로 Appmodule을 앱으로 만들어 포트를 할당해준다.

 

 

app.modules.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

이곳에서 AppController와 AppService 파일들을 가져와 모듈을 만들어준다.

 

 

 

app.controller.ts

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();
  }
}

이곳에서 AppService 파일을 import 하고 Controller를 만들어준다.

 

 

app.service.ts

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

마지막으로 Service에선 Controller에서 return할 때 쓰인 getHello()함수를 명시하여 선언해준다.

 

이 때 Controller에서 바로 return 'Hello World'를 쓸 수도 있는데 왜 굳이 Service를 만들어주어야 하는지 의문점이 들 수 있다. 구조와 아키텍처에 관한 설명이 필요하다.

 

Controller는 그저 Url을 가져오는 역할이며, Service는 비즈니스 로직을 만드는 역할을 수행한다.

즉, Controller는 Url에 따른 함수를 가져오게 하고,  Service가 그 함수가 되는 것이다.

 

Url에 따라 분명 똑같은 비즈니스 로직이 실행되어야 할 때가 있다. 그럴 땐 Service에서 지정한 함수를 Controller에서 재사용이 가능하며, 유지 및 보수를 할 때 해당 로직에 문제가 생길 경우 수정 또한 쉽게 할 수 있다.

728x90
반응형

'Back-End > Nest.js' 카테고리의 다른 글

Nest.js | REST API | Movies Controller  (0) 2021.09.24
Nest.js | 개요 | Modules  (0) 2021.09.24
Nest.js | 개요 | Controller(2)  (0) 2021.09.24
Nest.js | 개요 | Controllers(1)  (0) 2021.09.24
Nest.js | 개요 | 첫 번째 단계  (0) 2021.09.24
728x90
반응형

Route parameters

동적 데이터를 일부 수락해야 하는 경우 @Get() 데코레이터에서 파라미터를 정의해주는 방법이 있다.

@Get(':id')
findOne(@Param() params): string {
  console.log(params.id);
  return `This action returns a #${params.id} cat`;
}
@nestjs/common 패키지에서 Param을 가져옵니다.

 

 

Asynchronicity

모든 비동기 함수는  Promise를 반환해야 한다. Nest가 자체적으로 해결할 수 있는 지연된 값을 반환할 수 있다.

 

cats.controller.ts

@Get()
async findAll(): Promise<any[]> {
  return [];
}

 

 

Request payloads

 

이전 예제에서 POST 라우터의 매개변수를 다루지 않았다. 여기에 @Body() 데코레이터를 추가해 문제를 해결해보겠다.

그러기 전에 먼저 DTO( 데이터 전송 개체 )스키마를 결정해야 한다. 아래와 같이 할 수 있다.

export class CreateCatDto {
  name: string;
  age: number;
  breed: string;
}

 

그 다음 CatsController 내부에서 생성된 DTO를 사용할 수 있다.

 

cats.contoller.ts

@Post()
async create(@Body() createCatDto: CreateCatDto) {
  return 'This action adds a new cat';
}

 

 

Full resource sample

 

다음은 여러 데코레이터를 사용하여 기본 컨트롤러를 만드는 예제이다.

 

cats.controller.ts

import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
import { CreateCatDto, UpdateCatDto, ListAllEntities } from './dto';

@Controller('cats')
export class CatsController {
  @Post()
  create(@Body() createCatDto: CreateCatDto) {
    return 'This action adds a new cat';
  }

  @Get()
  findAll(@Query() query: ListAllEntities) {
    return `This action returns all cats (limit: ${query.limit} items)`;
  }

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

  @Put(':id')
  update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
    return `This action updates a #${id} cat`;
  }

  @Delete(':id')
  remove(@Param('id') id: string) {
    return `This action removes a #${id} cat`;
  }
}

 

 

728x90
반응형

'Back-End > Nest.js' 카테고리의 다른 글

Nest.js | 개요 | Modules  (0) 2021.09.24
Nest.js | 개요 | Service  (0) 2021.09.24
Nest.js | 개요 | Controllers(1)  (0) 2021.09.24
Nest.js | 개요 | 첫 번째 단계  (0) 2021.09.24
Next.js | 소개  (0) 2021.09.24

+ Recent posts