프로젝트를 진행하는 팀원의 개발 환경에서 Java에 대한 오류가 있는지 형태소 추출 오픈소스 프로그램이 제대로 동작하지 않았다.

    (https://github.com/koalanlp/nodejs-support 오픈소스 주소)

     

    따라서 이 프로그램을 내가 API형식으로 만들어서 팀원이 사용할 수 있도록 해보려고 한다.

     

    이는 개발 과정에서 필요한 것이기 때문에 예전부터 공부하려고 생각했던 NestJS를 공부하면서 API로 만들고자 한다.

     

     

    #0 Rest API란?

    API에 대해 공부하는 강의가 Rest api를 만드는 강의인데, 먼저 이 개념이 뭔지 정리해보자.

     

    API는 응용 프로그램이나 디바이스가 서로 연결하여 통신하는 방법론들이다.

     

    그리고 REST는 Representational State Transfer의 줄임말로 웹 어플리케이션 간의 통신을 위한 아키텍쳐 스타일을 말한다.

     

    따라서 Rest API는 HTTP Method(Get, Post, Put, Delete) 등을 사용하여 정보를 주고받는 형태이다.

     

    Rest API에 규칙은 (https://www.ibm.com/kr-ko/topics/rest-apis) 이와 같다.

     

    보다보니 특정 데이터를 전송해주는 API에 가까워서 지금 만들고자하는 기능을 수행하는 API로서는 완전히 적합해보이지는 않았으나, 만들 수 있을 것 같아서 공부할겸 진행해보기로 했다.

     

    프로젝트는 "검색 기록을 저장, 볼 수 있고, query문을 보내면 형태소가 분리되어서 값이 반환되는 Rest API이다."

     

     

    #1 환경 설정

    npm i -g @nest/cli

     

    nest를 입력했을 때 명령어 목록이 나오면 성공적으로 설치가 된 것이다.

     

    nest new

    위 명령어로 새로운 프로젝트를 생성한다.

     

    NestJS는 프레임워크 답게 src 폴더 하위에 main.ts 파일이 있는데 여기서 프로젝트가 시작된다.

     

    여기서 module을 실행하는 것을 볼 수 있는데 따라가보면 decorator 함수를 통해 모듈이 class로 선언되어있는 것을 볼 수 있다.

    //app.module.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 {}

     

    데코레이터는 간단하게 class에 함수 기능을 추가한다고 생각하면 된다.

    특히 함수의 기능 중, 인자를 받는 기능이 핵심이다.

     

    module << controller << service 방향으로 정보가 이동하는 것 같은 구조이다. (module이 가장 큼)

     

     

    #2 NestJS에서 Module과 Controller

    1) 먼저 module.

    app.module의 경우 모든 모듈의 루트 모듈과 같은 개념이다.

     

    모듈이란 영단어 뜻 그대로 전체 어플리케이션에 특정 기능을 담당하는 일부분의 단위인데, 다음과 같이 선언한다.

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

    여기서 controller와 provider가 module의 핵심적인 인자이다.

     

    controller는 MVC패턴에 등장하는 개념처럼 url을 가져오고 함수를 실행하는 역할이다. express에서는 Router와 같다. (express에서는 Router가 Controller를 불러오지만 NestJS에서는 하나의 기능으로 합친 느낌)

     

    이제 controller의 구조는 아래와 같다,

    @Controller()
    export class AppController {
      constructor(private readonly appService: AppService) {}
    
      @Get()
      getHello(): string {
        return this.appService.getHello();
      }

    @Get 데코레이터의 경우, express에 get router처럼 controller의 기능을 한다.

     

     

    #3 Service

    NestJS는 Controller를 비지니스 로직과 구분하고자 함.

    express에서 router와 controller 기능이 구분해둔 것과 유사함. express의 router기능이 NestJS에서 Controller이고,

    express에서 controller 기능이 NestJS에서 Service의 기능과 유사하다고 생각하면 된다.

     

    즉,

     

    express 의 router == NestJS의 Controller == (URL을 가져오고 다음 함수를 불러주는 역할)

     

    express의 controller == NestJS의 Service == (URL에서 실행할 기능들)

     

    이라고 볼 수 있다.

     

    아래와 같이 사용한다.

    getHello(): string {
        return this.appService.getHello();
      }
      
    //appService.getHello로 Service에 있는 함수 불러옴
    
    //app.service폴더
    @Injectable()
    export class AppService {
      getHello(): string {
        return 'Hello World!';
      }
      //getHi() 등으로 추가 가능
    }

     

     

     

    #4 CLI 활용하여 NEST js 기능 이용하기

    Controller같은 요소들을 사용자가 직접 만들수도 있지만 명령어를 통해서 좀 더 쉽게 생성할 수 있다.

     

    nest를 입력하면 명령어 목록을 볼 수 있음.

     

    1) Controller 생성

    nest g co

     

     

    #5 Get 을 다루면서 Param의 개념 확인하기

    @Get("/:query")
    getOne(@Param("query") queryStr: string){
        return `this will seperated return morphem: ${queryStr}`
    }

    위와 같은 형태로 사용하는데, Param을 사용하기 위해서는 선언하듯, @Param을 앞에 먼저 꼭 써줘야한다.

     

     

    #6 다양한 Decorator 테스트

    {
        "Id" : 1,
        "Query" : "글라골문자"
    }

    위와 같은 body를 가진 데이터를 Http method로 주고받는다고 가정하자.

    post를 사용한다고 하면 다음과 같이 데코레이터를 활용한다.

     

    @Post()
    create(@Body() queryData){
        return queryData;
    }

    위와 같이 사용해준다.

     

    id를 기준으로 값을 업데이트 해주고 싶다면

    @Patch("/:query")
    path(@Param("query") queryId:string, @Body() updatedQuery){
        return {
            updatedQueryId: queryId,
            ...updatedQuery,
        };
    }

     

    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기