본 캠프 13일차 TIL

정희준·2023년 3월 30일
0
post-thumbnail

📌 오늘의 내용

오늘은 새로운 프레임워크인 Nest를 설치하고 간단한 실습을 해보았다
오늘의 내용에 대해 복습해보자!

Nest

Nest에 대한 설명은 아래 링크를 참조!
https://velog.io/@gmlgml98/Nest


NestJS 폴더 구조

Nest를 설치하게 되면 위와 같이 유명하고 유용한 라이브러리들이 자동으로 설치되며 위와 같은 구조가 잡혀있다
이 초기 구조를 보일러 플레이트라고 한다!

자동으로 셋팅해준 package.json 을 살펴보자

단축 명령어(scripts)

// package.json

"scripts": {
    "prebuild": "rimraf dist",
    "build": "nest build",
    "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
    "start": "nest start",
    "start:dev": "nest start --watch",
    "start:debug": "nest start --debug --watch",
    "start:prod": "node dist/main",
    "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:cov": "jest --coverage",
    "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
    "test:e2e": "jest --config ./test/jest-e2e.json"
  },
  • 시작하는 부분은 "start": "nest start" 의 start 로 실행해 주시면 됩니다.
    • 개발할 때 : "start:dev" 사용 (dev 는 development 의 약자) ⇒ 우리가 사용할 명령어
    • 배포할 때 : "start:prod" 사용 (prod 는 production 의 약자)
  • Nest 자체에서 nodemoon 기능을 제공해주고 있기에 nodemoond은 필요 없게 됩니다. ( "start:dev": "nest start --watch" ⇒ watch : 소스코드가 바뀌면 자동으로 리프레쉬 해주는 것 )
  • test : 배포전에 테스트 코드를 작성해서 실행시켜 봄으로 모든 API가 제대로 작동하는지 확인하는 것으로 보다 안전한 개발을 하기 위한 것입니다.

설치 목록 dependencies, devDependencies

// package.json

"dependencies": {
    "@nestjs/common": "^8.0.0",
    "@nestjs/core": "^8.0.0",
    "@nestjs/platform-express": "^8.0.0",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.2.0"
  },
  "devDependencies": {
    "@nestjs/cli": "^8.0.0",
    "@nestjs/schematics": "^8.0.0",
    "@nestjs/testing": "^8.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "^27.0.1",
    "@types/node": "^16.0.0",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^4.28.2",
    "@typescript-eslint/parser": "^4.28.2",
    "eslint": "^7.30.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^3.4.0",
    "jest": "^27.0.6",
    "prettier": "^2.3.2",
    "supertest": "^6.1.3",
    "ts-jest": "^27.0.3",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.0.0",
    "tsconfig-paths": "^3.10.1",
    "typescript": "^4.3.5"
  },
  • dependencies : 백엔드 서버를 실행시킬 때 필요한 모듈들이 위치합니다.
  • devDependencies : VS code 내에서 개발할 때 필요한 모듈들이 위치합니다.

jest

// package.json

"jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }

jest는 테스트 관련된 부분입니다.
마우스로 하나하나 클릭해서 테스트해 볼 수 있지만, 백엔드는 보통 보이지 않기 때문에, 명령어를 이용해서 파일을 실행해서 테스트합니다.


NestJS started with GraphQL & TypeScript

시작하기 앞서 Schema First와 code first에 대해 간략히 알아보자!


나는 자동으로 스키마를 만들어주는 Code-Frist로 실습해볼 것 이다!

graphQl을 사용하기 위해! nestjs 공식문서에 GRAPHQL → Quick start 에 나와있는 명령어를 통해 설치를 진행 하자

$ yarn add @nestjs/graphql @nestjs/apollo graphql apollo-server-express

설치 진행 후! nestJs의 공식 git 사이트에 sample을 참고하여 graphql 구조를 잡아보자

sample을 참고하여 게시판,상품,유저 기능이 있다고 가정하여 만들어 보았다

게시판 api를 실행 시켜보자!
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();

app.module.ts

import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { BoardsModule } from './apis/boards/boards.module';

@Module({
  imports: [
    BoardsModule,
    // PrdocuctsModule,
    // UsersModule
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'src/commons/graphql/schema.gql',
    }),
  ],
})
export class AppModule {}

boards.module.ts

import { Module } from '@nestjs/common';
import { BoardsResolver } from './boards.resolver';
import { BoardsService } from './boards.service';

@Module({
  imports: [],
  controllers: [],
  providers: [
    BoardsResolver, //
    BoardsService,
  ],
})
export class BoardsModule {}

boards.resolver.ts

import { Query, Resolver } from '@nestjs/graphql';
import { BoardsService } from './boards.service';

@Resolver()
export class BoardsResolver {
  constructor(private readonly boardsService: BoardsService) {}

  @Query(() => String, { nullable: true })
  fetchBoards(): string {
    return this.boardsService.getHello();
  }
}

board.services.ts

import { Injectable, Scope } from '@nestjs/common';
// 인젝션-스코프 =>  1. 싱글톤(new 한 번)으로 할래?
//            =>  2. Request 스코프( 매 요청마다 new) 할래?
//            =>  3. Transient 스코프(매 주입마다 new)로 할래?
@Injectable({ scope: Scope.DEFAULT }) // 기본값 => 싱글톤
export class BoardsService {
  getHello(): string {
    return 'Hello 철수!';
  }
}

위 예제 코드를 살펴보자
NestJs에선 DI를 자동으로 해주기 때문에
boards.module 파일을 보면 providers에 BoardsResolver와BoardsService를 DI 시켜라! 라고 적어놓았다

그리고 boards.resolver -> 쉽게 생각해 컨트롤러 라고 생각하면 되고 fetchBoards에 약간의 옵션을 붙여줌으로써 자동으로 스키마가 생성 된다!

boards,products,user 모두 이와 같은 구조로 설계되며
app.module에서 api 기능들을 모두 담아주며 main.ts에서 모든게 담겨진 모듈을 실행 시키는 구조이다! -> index.js와 같다고 보면 된다


하루를 마치며:)

이전 수업때 배웠었던 rest-api구조를 Nest 프레임워크를 사용한 graphql로 변환해봤는데 아직은 조금 낯설다 하지만 스키마를 자동으로 생성해주는것은 매우 편리 하다!!

profile
같이 일하고 싶은 사람이 되어보자! 다시 시작하는 개발 블로그.

0개의 댓글