Nest & GraphQL

류연찬·2023년 5월 17일
0

GraphQL

목록 보기
10/17

MySQL 설치

brew 를 이용해 설치해보겠습니다.

터미널을 열어 brew update 입력 후, brew install mysql 을 입력해 설치해주세요.

brew update
brew install mysql

설치가 완료되면 brew services start mysql 을 입력해주세요.

brew services start mysql

이 상태로도 사용할 수 있지만, 보안을 위해 비밀번호 설정을 해줘야합니다.

터미널에 mysql_secure_installation 을 입력합니다.

mysql_secure_installation

복잡한 비밀번호를 사용할 것이냐는 질문에N 를 입력하고 엔터를 칩니다.

New Password: 라고 나오면, 비밀번호를 입력하고 엔터를 쳐서 실행합니다.

Re-enter new password: 비밀번호를 다시 입력합니다.

익명의 유저를 삭제하는데 동의하냐는 질문에 y 를 입력합니다.

n 을 입력해 root의 원격 접속을 허용합니다.

n 을 입력해 test 데이터베이스를 유지합니다.

y 를 입력해 변경된 권한을 테이블에 적용합니다.

MySQL 접속

터미널에 mysql -u root -p 라고 입력한 뒤, 방금 설정한 비밀번호를 입력합니다.

mysql> 처럼 터미널에 바뀌면 성공입니다.

DB 관리 툴 설치 - DBeaver

DBeaver 공식 홈페이지에 접속해서 Download를 눌러줍니다.

본인 컴퓨터 OS에 맞는 설치 프로그램을 다운로드하고 설치해줍니다.



NestJS started with GraphQL & TypeScript

이전에는 NestJS와 Rest-API & TypeScript를 사용했지만 이번에는 GraphQL & TypeScript를 사용하는 방법에 대해 알아보겠습니다.

Nest는 GraphQL 애플리케이션을 빌드하는데 코드 우선(code first)스키마 우선(schema first) 방법을 제공합니다.

Code First(코드 우선)

코드 우선 접근 방식에서는 데코레이터의 TypeScript 클래스를 사용하여 해당 GraphQL 스키마를 생성합니다.

이 방법은 TypeScript으로만 작업하고 언어 구문 간의 컨텍스트 전환을 피하려는 경우 유용합니다.

코드 우선 접근 방식을 사용하려면 먼저 옵션 객체에 autoShcemaFile 속성을 추가합니다.

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  autoSchemaFile: 'src/commons/graphql/schema.gql`,
})

autoSchemaFile 속성 값은 자동으로 생성된 스키마라 생성될 경로입니다.

Schema First(스키마 우선)

스키마 우선 접근 방식에서 진실된 소스는 GraphQL SDL(Schema Definsion Language) 파일입니다.

모든 프로그래밍 언어와 독립적이며, 통합되는 언어이고, NestJS 에서는 GraphQL 스미카를 TypeScript 의 클래스 및 인터페이스 형식으로 구현됩니다.

GraphQL 스키마를 기반으로 TypeScript 정의(클리스 또는 인터페이스 사용)를 자동으로 생성하여 중복된 상용구 코드를 작성할 필요성을 줄여줍니다.

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloDriver,
  typePaths: ['./**/*.graphql'],
})

스키마 우선 접근 방식을 사용하려면 먼저 옵션 개체에 typePaths 속성을 추가합니다.

typePaths 속성은 GraphQLModule 이 작성할 GraphQL SDL 스키마 정의 파일을 찾아야하는 위치를 나타냅니다.

// cat.graphql

type Query {
	cats: [Cat]
	cat(id: ID!): Cat
}

type Mutation {
	createCate(createCateInput: CreateCatInput): Cat
}

type Subscription {
	catCreated: Cat
}

type Owner {
	id: Int!
    name: String!
    age: Int
    cats: [Cat!]
}

type Cat {
	id: Int
	name: String
    age: Int
    owner: Owner
}

input CreateCatInput {
	name: String
	age: Int
}

아래처럼 .graphql 로 스키마를 직접 작성해줘야 합니다.

code first는 typescript로 클래스를 짜면 해당 클래스에 해당하는 graphql schema를 만들어주고 schema first는 graphql schema를 먼저 짠 후 typescript 클래스나 인터페이스를 생성해줍니다.

NestJS with GraphQL(Code First)

typescript에 좀 더 익숙해지기 위해서 code first 방식으로 애플리케이션을 빌드 하겠습니다.

[Github] nestjs - graphql-code-first 예제

13-01-nestjs-with-graphql 프로젝트를 생성합니다.

터미널에 nest new 13-01-nestjs-with-graphql 를 입력해서 새로운 프로젝트를 생성해주세요.

생성된 폴더에 들어가yarn add @nestjs/graphql @nestjs/apollo @apollo/server graphql 를 GraphQL을 사용하기 위해 필요한 패키지를 설치해주세요.

// package.json

{
  "name": "13-01-nestjs-with-graphql",
  "version": "0.0.1",
  "description": "",
  "author": "",
  "private": true,
  "license": "UNLICENSED",
  "scripts": {
    "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"
  },
  "dependencies": {
    "@apollo/server": "^4.7.1",
    "@nestjs/apollo": "^11.0.5",
    "@nestjs/common": "^9.0.0",
    "@nestjs/core": "^9.0.0",
    "@nestjs/graphql": "^11.0.5",
    "@nestjs/platform-express": "^9.0.0",
    "graphql": "^16.6.0",
    "reflect-metadata": "^0.1.13",
    "rxjs": "^7.2.0"
  },
  "devDependencies": {
    "@nestjs/cli": "^9.0.0",
    "@nestjs/schematics": "^9.0.0",
    "@nestjs/testing": "^9.0.0",
    "@types/express": "^4.17.13",
    "@types/jest": "29.5.0",
    "@types/node": "18.15.11",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "29.5.0",
    "prettier": "^2.3.2",
    "source-map-support": "^0.5.20",
    "supertest": "^6.1.3",
    "ts-jest": "29.0.5",
    "ts-loader": "^9.2.3",
    "ts-node": "^10.0.0",
    "tsconfig-paths": "4.2.0",
    "typescript": "^4.7.4"
  },
  "jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }
}

nextjs docs에 따라 app.module.ts 파일의 코드를 아래와 같이 수정해줍니다.

// app.module.ts

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

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

클래스 선언 위에 @module() 를 붙여서 '얘는 모듈로 쓸꺼야' 라고 nest한테 알려주고 있습니다.

이런 골뱅이는 데코레이터라고 했습니다.

app.module 을 열어 GraphQLModule 을 가져와 프로젝트에 장착해주세요.

forRoot() 메서드는 옵션 객체를 인수로 받을 수 있으며, 이 옵션은 ApolloServer 생성자(constructor)에 전달됩니다.

서버를 실행하게되면 type이 자동으로 생성되는데 그 파일의 위치를 autoSchemaFile 을 통해 지정한다.



nest g module board : board module 생성 명령어
nest g service board : board service 생성 명령어
nest g resolver board : board resolver 생성 명령어

다음 명령어를 입력하면 src 폴더안에 board 라는 폴더가 생성됩니다.

board 라는 폴더 안에는 module service resolver 가 생성됩니다.

// board.service.ts

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

@Injectable()
export class BoardService {
  aaa() {
    return 'Hello World!';
  }
}

board.service 에 문자열 "Hello World!" 를 반환하는 getHello 라는 비즈니스 로직을 다음과 같이 만들어 주세요.

// board.resolver.ts

import { Resolver, Query } from '@nestjs/graphql';
import { BoardService } from './board.service';

@Resolver()
export class BoardResolver {
  constructor(private readonly boardService: BoardService) {}

  // 기존에는 GET 이지만 GraphQL에서는 Query를 사용
  @Query(() => String)
  getHello() {
    return this.boardService.aaa();
  }
}

클라이언트 아직 DB와 상호 작용할 수 있는 방법이 없습니다.

이를 해결하려면 Resolver 클래스를 만들어야 합니다.

코드 우선 방법에서 리졸버 클래스는 Resolver 함수를 정의하고 쿼리 유형을 생성합니다.

Routing 개념을 적용하여 어떤 Resolver가 어떤 Request를 수신하는지 제어합니다.

각 Resolver는 최소 1개의 Route를 가지며 각 Route는 다른 action으로 동작합니다.

constructorBoardService 를 주입해 주시고 getHello 라는 Resolver 함수를 만들어 BoardServicegetHello 비즈니스 로직을 실행시켜 주세요.

src 폴더 안에 apis 폴더를 만들어주시고 Board 폴더 전체를 apis 폴더로 안으로 이동시켜 주세요.

폴더 구성은 위와 같습니다.

yarn start:dev 를 입력해서 서버를 실행시켜주세요.

그러면 아래와 같이 commons/graphql/schema.gql 파일이 생성되었습니다.

# ------------------------------------------------------
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
# ------------------------------------------------------

type Query {
  getHello: String!
}

schema.gql 파일에 getHello 의 반환될 타입이 자동으로 기록됩니다.

http://localhost:3000/graphql 에 접속해서 위와 같은 화면이 나온다면 성공입니다.

NestJS connected with MySQL

이번에는 typeorm을 활용해서 nestjs와 mysql을 연결해보겠습니다.

13-01-nestjs-with-graphql 폴더를 복사해 사본을 만들고 폴더명을 13-02-nestjs-with-typeorm 으로 변경해주세요.

nestjs에서 typeorm, mysql을 이용하기 위해 yarn add @nestjs/typeorm typeorm mysql2 을 통해 설치해주세요

직접 타입스크립트를 이요해서 entity를 작성해보겠습니다.

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Board {
  @PrimaryGeneratedColumn('increment')
  number: number;

  @Column()
  writer: string;

  @Column()
  title: string;

  @Column()
  contents: string;
}

/src/apis/board/entities/board.entity.ts 경로에 board.entity.ts 파일을 생성해주세요.

typeorm의 데코레이터를 이용해 key: value 형태로 타입을 지정해주세요.

// board.service.ts

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

@Injectable()
export class BoardService {
  findAll(): string {
    // 데이터 조회하는 로직
    return '조회에 성공했습니다.';
  }

  create(): string {
    // 데이터 등록하는 로직
    return '등록에 성공했습니다.';
  }
}

위와 같이 findAllcreate 의 비즈니스 로직을 작성해주세요.

// board.resolver.ts

import { Resolver, Query, Mutation } from '@nestjs/graphql';
import { BoardService } from './board.service';

@Resolver()
export class BoardResolver {
  constructor(private readonly boardService: BoardService) {}

  @Query(() => String)
  fetchBoards(): string {
    return this.boardService.findAll();
  }

  @Mutation(() => String)
  createBoard(): string {
    return this.boardService.create();
  }
}

board.resolver.ts 코드를 수정해주세요.

조회를 할 때는 Query , 등록, 수정, 삭제를 할 때는 Mutation 을 사용합니다.

typeormQueryMutation을 데코레이터 형태로 사용했습니다.

constructorBoardService 를 주입해 주었습니다.

BoardServicefindAllcreate 의 비즈니스 로직을 실행시켜 주세요.

import { Module } from '@nestjs/common';
import { ApolloDriverConfig, ApolloDriver } from '@nestjs/apollo';
import { GraphQLModule } from '@nestjs/graphql';
import { BoardModule } from './apis/board/board.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Board } from './apis/board/entities/board.entity';

@Module({
  imports: [
    BoardModule,
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'src/commons/graphql/schema.gql',
    }),
    TypeOrmModule.forRoot({
      type: 'mysql', // 데이터베이스 타입
      host: 'localhost', // local 환경으로 진행
      port: 3306, // mysql은 기본 포트는 3306
      username: 'root', // nysql은 기본 user는 root로 지정
      password: '설정한 비밀번호', // 설치 과정에서 설정한 비밀번호
      database: 'myproject', // 연결할 데이터베이스명
      entities: [Board], // 데이터베이스와 연결할 entity
      synchronize: true, // 연결과 동시에 테이블을 초기화 혹은 생성할 것인지
      logging: true, // 콘솔창에 log를 표시하는지
    }),
  ],
})
export class AppModule {}

MySQL과 연결시켜주기 위해서 TypeOrmModule 의 옵션을 설정하였습니다.

현재 데이터베이스 myproject 가 존재하지 않기때문에 생성해주겠습니다.

우선 터미널에서 brew services restart mysql 로 재시작을 해줍니다.

그리고 DBeaver에 접속하여 좌측 상단의 플러그 아이콘을 클릭하여 비밀번호를 입력하고 Test Connection을 눌러줍니다.

통과가 되면 완료를 눌러주시면 됩니다.

🚨 Public Key Retrieval is not allowed 에러
아래와 같이 Driver Properties 메뉴에 들어가 allowPulicKeyRetrievalTRUE 로 변경해줍니다.

성공적으로 접속이 되면 아래와 같이 뜨는 것을 확인하실 수 있습니다.

현재 Databases 에는 sys 밖에 없는 것을 확인하실 수 있습니다.

그리고 Databases 에 우클릭해서 Create New Database를 눌러 데이터베이스를 하나 추가해줍니다.

이름은 app.module.ts 에 명시해준 데이터베이스와 동일하게 만들어줍니다.

그러면 Databases 안에 myproject 라는 데이터베이스가 생성된 것을 확인하실 수 있습니다.

데이터베이스를 생성했으니 이제 서버를 실행해보겠습니다.

yarn start:dev 명령어로 서버를 작동시킵니다.

그리고 DBeaver를 통해 테이블이 생성되었는지 확인해보겠습니다.

그리고 schema.gql 파일에 resolver에 지정한 반환값의 타입이 자동으로 기록됩니다.

또한 http://localhost:3000/graphql 에 접속해서 다음과 같은 화면이 나온다면 정상입니다.



Board CRUD API

fetchBoards

13-02-nest-js-with-typeorm 폴더를 복사하고 사본을 만든 후 폴더명을 13-03-graphql-api-fetchboards 으로 변경합니다.

이전에는 fetchBoards 을 사용해 게시판을 조회했을 때는 '조회에 성공했습니다.' 라는 문자열을 반환했습니다.

이번에는 작성한 Board.entity 형식에 맞게 반환하는 API로 수정하겠습니다.

// board.entity.ts

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity() // typeorm한테 알려줌(mysql)
@ObjectType() // gql한테 알려줌
export class Board {
  @PrimaryGeneratedColumn('increment')
  @Field(() => Int)
  number: number;

  @Field(() => String)
  @Column()
  writer: string;

  @Field(() => String)
  @Column()
  title: string;

  @Field(() => String)
  @Column()
  contents: string;
}

05-03-graphql-api-with-apollo-server-3 안에 index.js 안에 fetchBoards 에 있는 return 값을 복사해서 board.service.tsfindAll 함수 안에 return 값으로 넣어줍니다.

// board.service.ts

import { Injectable } from '@nestjs/common';
import { Board } from './entities/board.entity';

@Injectable()
export class BoardService {
  findAll(): Board[] {
    // 1. 데이터 조회하는 로직 => DB에 접속해서 가져오기

    // return '조회에 성공했습니다.';

    const result: Board[] = [
      { number: 1, writer: '철수', title: '제목입니다~', contents: '내용!!' },
      {
        number: 2,
        writer: '영희',
        title: '안녕하세요~',
        contents: '배고프네요',
      },
      {
        number: 3,
        writer: '훈이',
        title: '점심은 맛있게 드셨나요?',
        contents: '식사는 하셨나요?',
      },
      {
        number: 4,
        writer: '맹구',
        title: '안녕하세요!!!',
        contents: '내용입니다~',
      },
    ];

    // 2. 꺼내온 결과 응답 주기
    return result;
  }

  create(): string {
    // 1. 데이터 등록하는 로직 => DB에 접속해서 저장하기

    // 2. 저장 결과 응답 주기
    return '등록에 성공했습니다.';
  }
}
// board.resolver.ts

import { Field, Int, ObjectType } from '@nestjs/graphql';
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity() // typeorm한테 알려줌(mysql)
@ObjectType() // gql한테 알려줌
export class Board {
  @PrimaryGeneratedColumn('increment')
  @Field(() => Int)
  number: number;

  @Field(() => String)
  @Column()
  writer: string;

  @Field(() => String)
  @Column()
  title: string;

  @Field(() => String)
  @Column()
  contents: string;
}

한번 yarn start:dev 로 서버를 실행시켜보겠습니다.

그리고 http://localhost:3000/graphql 에서 확인해보겠습니다.

위와 같은 화면이 나온다면 정상입니다.

createBoard

13-03-graphql-api-fetchboards 폴더를 복사하여 사본을 만들고 폴더명을 13-04-graphql-api-createBoard 으로 변경합니다.

createBoard 에서 Args 개별로 받아서 등록에 성공하였다는 메시지를 받아보게 수정하겠습니다.

// board.resolver.ts

import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
import { BoardService } from './board.service';
import { Board } from './entities/board.entity';

@Resolver()
export class BoardResolver {
  constructor(private readonly boardService: BoardService) {}

  @Query(() => [Board]) // graphql에게 타입을 알려준다
  fetchBoards(): Board[] {
    return this.boardService.findAll();
  }

  @Mutation(() => String)
  createBoard(
    @Args('writer') writer: string,
    @Args('title') title: string,
    @Args('contents') contents: string,
  ): string {
    console.log(writer);
    console.log(title);
    console.log(contents);
    return this.boardService.create();
  }
}

@Args 는 데코레이터로 '@nestjs/graphql' 에서 import 해 사용하는데 gql에 arguments라고 알려줍니다.

@Args('writer') writer: string,
@Args('title') title: string,
@Args('contents') contents: string,

@Args() 데코레이터를 사용해서 객체 value 값의 타입을 지정했습니다.

@Args() 안은 gql 타입이고, 그 뒤는 타입스크립트의 타입을 의미합니다.

하지만 저렇게 하나씩 넣는게 아닌 객체하나로 통일해서 넣으려고 합니다.

src/apis/board/dto 경로에 createBoard.input.ts 를 생성하고 아래의 코드를 작성합니다.

💡 createBoardInput 은 재사용성이 없기때문에 dto 라는 폴더를 새로 생성에 거기에 놓고 보관합니다

import { Field, InputType } from '@nestjs/graphql';

@InputType()
export class CreateBoardInput {
  @Field(() => String)
  writer: string;

  @Field(() => String)
  title: string;

  @Field(() => String)
  contents: string;
}

그리고 다시 resolver로 돌아가 args를 수정합니다.

import { Resolver, Query, Mutation, Args } from '@nestjs/graphql';
import { BoardService } from './board.service';
import { Board } from './entities/board.entity';
import { CreateBoardInput } from './dto/createboard.input';

@Resolver()
export class BoardResolver {
  constructor(private readonly boardService: BoardService) {}

  @Query(() => [Board]) // graphql에게 타입을 알려준다
  fetchBoards(): Board[] {
    return this.boardService.findAll();
  }

  @Mutation(() => String)
  createBoard(
    @Args('createBoardInput') createBoardInput: CreateBoardInput,
  ): string {
    console.log(createBoardInput);
    return this.boardService.create();
  }
}

그리고 yarn start:dev 로 서버를 실행하고 http://localhost:3000/graphql 에 들어가서 직접 요청을 해보겠습니다.

정상적으로 잘 작동합니다.

Docker Packaging

graphql-docker-compose(connted with local mysql)

13-04-graphql-api-createboard 폴더를 복사하여 사본을 만들고 폴더명을 13-06-nestjs-with-graphql-docker-compose 으로 변경합니다.

이전에 MongoDB와 Node.js 서버를 docker container에서 실행했었습니다.

이번에는 NestJS 서버를 docker compose에서 실행시키고 local에서 실행 중인 mysql과 연결시켜보겠습니다.

dockerfile 은 다음과 같습니다.

FROM node:16

WORKDIR /backend/

COPY ./package.json .
COPY ./yarn.lock .
RUN yarn install

COPY . .
CMD node dist/main.js

실행파일은 index.js 가 아닌 dist/main.js 으로 지정해줍니다.

docker-compose.yaml 은 다음과 같습니다.

version: '3.3'

services:
  backend:
    build:
      context: .
      dockerfile: dockerfile
    volumes:
      - ./src:/backend/src
    ports:
      - 3000:3000

이번에는 volumes 가 추가되었습니다.

volumes./src 경로에 있는 파일과 docker의 backend/src 의 파일이 서로 다르면 새롭게 images를 빌드하는 옵션입니다.

이제 docker를 실행시켜주고 docker compose build 를 입력해 image를 빌드하고 docker compose up 을 입력해 container를 실행시켜보겠습니다.

🚨 The path 13-05-nestjs-with-graphql-docker-compose/src is not shared from the host and is not known to Docker. 에러

Docker에서 우측 상단 톱니바퀴를 눌러 Settings에 접속합니다.
그리고 좌측 메뉴에서 Resources -> File Sharing에 들어가서 서버를 실행할 폴더 경로를 지정해주면 됩니다.

서버는 잘 실행되었지만 NestJS가 datase를 연결하지 못했습니다.

NestJS에서는 database를 container 환경을 구성해야지만 연결이 가능합니다.

local에 있는 database를 연결할 수 없습니다.

docker-compose.yaml 파일을 수정하겠습니다.

version: '3.3'

services:
  backend:
    build:
      context: .
      dockerfile: dockerfile
    volumes:
      - ./src:/backend/src
    ports:
      - 3000:3000

  database:
    platform: linux/x86_64
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: '설정한 비밀번호'
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --skip-character-set-client-handshake
    cap_add:
      - SYS_NICE
    ports:
      - 3306:3306

database 는 데이터베이스를 구성하는 부분입니다.

environment 는 mysql 설정하는 부분입니다.

command 는 데이터베이스 생성하는 부분입니다.

app.module.ts 의 host와 password를 다음과 같이 변경해주세요.

docker container의 데이터베이스와 연결시켜주기 위해서 입니다.

import { Module } from '@nestjs/common';
import { ApolloDriverConfig, ApolloDriver } from '@nestjs/apollo';
import { GraphQLModule } from '@nestjs/graphql';
import { BoardModule } from './apis/board/board.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Board } from './apis/board/entities/board.entity';

@Module({
  imports: [
    BoardModule,
    GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: 'src/commons/graphql/schema.gql',
    }),
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'database',	// local -> database
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'mysql',
      entities: [Board],
      synchronize: true,
      logging: true,
    }),
  ],
})
export class AppModule {}

passworddatabase 는 꼭 default 값으로 해줘야합니다.

docker에서 새로운 환경을 구축하기때문에 mysql의 root 계정은 ID: root , PASSWORD: root 으로 되어있으며 데이터베이스는 기본 mysql DB로 설정해야합니다.

docker-packaging 전에 local에서 실행하던 mysql 서버를 종료시켜주세요.

.yaml 파일에 이미 3306을 사용하게 해 놓았기 때문입니다.

그리고 docker compose build 를 입력해 서버, 데이터베이서 image를 생성해주세요.

docker compose up 을 입력해 container를 실행시켜주세요.

처음에 실행 속도 차이때문에 약간의 딜레이는 있어서 retry하는 경우도 있습니다.

http://localhost:3000/graphql 에 접속하니 정상적으로 동작합니다.

0개의 댓글