Koa + MongoDB + Apollo Server + GraphQL 연동하기

sangminnn·2020년 4월 18일
1

GraphQL 사용기

목록 보기
1/2

시작하며 ...

요즘 공부하는 것중 Redux를 대체할 수 있는 Apollo + GraphQL 을 활용해서 새로운 프로젝트를 만들어보려고 하는데

프론트 위주로 공부하다보니 아무래도 백엔드는 다룰 줄 아는게 한정적인 것이 현실 ...

일단은 이전 프로젝트에서 다뤄봤던 Koa + MongoDB + Mongoose 를 백엔드로 잡고 이를 연동하기로 함.

둘러보면 Koa랑 MongoDB를 연동하시는 개발자분은 별로 못봐서 과정을 글로 남기기로 했음.

코드 설명

1. 프로젝트 생성

일단 프로젝트를 시작하기 위해 프로젝트를 만들어준다.

mkdir mongo-apollo-project
cd mongo-apollo-project
yarn init

2. 사용해야하는 모듈 세팅

이후 사용해야하는 모듈을 설치해준다.

yarn add koa koa-bodyparser apollo-server-koa graphql mongoose nodemon dotenv

또한, 이미 ES6의 module에 익숙해져있기 때문에 편의를 위해서 babel도 같이 설치해주겠다.

++) CommonJS문법을 그대로 사용하실 분들은 아래의 과정은 생략해도 됩니다 :)

yarn add babel @babel/core @babel/node @babel/preset-env --dev

2-1. babel 및 nodemon 세팅

ES6의 모듈을 사용하기 위해 babel에 관한 모듈을 설치했기 때문에, 이를 먼저 세팅해주어야한다.

먼저 프로젝트 루트에 .babelrc 파일을 만들어주고 다음 코드를 작성 후 저장해준다.

// .babelrc

{
  "presets": ["@babel/preset-env"]
}

그 다음은 nodemon과 babel을 프로젝트 실행 시에 작동시켜주어야 하기 때문에 package.json을 세팅해주어야한다.

나는 start 명령어 대신 개발 단계에서는 start:dev 로 하는 방법을 선택하여 아래와 같이 코드 작성.

"scripts": {
    // ....
    "start:dev": "NODE_PATH=src nodemon --exec babel-node src/index.js"
}

이후 프로젝트 실행 시에 yarn start:dev 로 실행해주면 babel과 nodemon이 적용된 상태로 실행된다.

3. index.js 세팅

3-1 koa, apollo-server 관련 모듈 선언

그 다음은 프로젝트에 mongodb, apollo server를 연결해주는 과정을 거친다.

나는 dotenv를 사용하여 MONGO_URI와 PORT 번호를 세팅해주는 방식을 선택하여

index.js 의 최상단에는 dotenv를 먼저 연결해주었다.

require('dotenv').config();

import Koa from 'koa';
import bodyParser from 'koa-bodyparser';
import { ApolloServer } from 'apollo-server-koa';
import mongoose from 'mongoose';

const app = new Koa();

// port 상수 세팅
const port = process.env.PORT || 4000;

그 다음 mongoose를 Promise문법을 사용해 보다 간결하게 연결에 대한 성공, 실패를 확인하기 위해

global객체의 Promise를 mongoose에 할당해주고, 이에 대한 코드를 작성해준다.

3-2. mongoose 연결


mongoose.Promise = global.Promise;

mongoose.connect(process.env.MONGO_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true
}).then(
  (response) => {
    console.log('Successfully connected to mongodb');
  }
).catch(e => {
  console.error(e);
});

3-3. koa middleware 및 port 연결

기본 세팅이기때문에 일단은 koa-bodyparser만 middleware로 연결해주고

정해둔 포트를 연결해주는 코드를 작성한다.

ApolloServer는 일단 인자가 필요하기때문에 주석으로 코드를 작성.

app.use(bodyParser());

// const apollo = new ApolloServer({
//  schema
// });

// apollo.applyMiddleware({ app });

app.listen(port, () => {
  console.log('good connection in port ' + port);
});

4. typeDefs, resolver 연결

Apollo Server는 기본 인자로 typeDefs와 resolver가 필요하기 때문에 이를 연결해 주어야하는데

프로젝트의 규모가 커질 것을 예상하여 schema별로 파일을 나누어 주고

schema들을 합쳐주는 schema.js 파일을 따로 만들어준다.

// src/graphql/pictures.js

// import pictures from '../database/pictures';
import { gql } from 'apollo-server-koa';

export const typeDef = gql`
  type Picture {
    image: String!
    title: String!
  }

  type Query {
    pictures: [Picture]!
  }

  type Mutation {
    addPicture(image: String!, title: String!): Picture!
  }
`;

export const resolvers = {
  Query: {
    pictures: () => pictures
  },
  Mutation: {
    addPicture: (_, { image, title }) => {
      const newPicture = {
        image,
        title
      };
      pictures.push(newPicture);
      return newPicture;
    }
  }
};

// src/graphql/schema.js

import merge from 'lodash/merge';
import * as pictures from './pictures';
import { makeExecutableSchema } from 'apollo-server-koa';



const schema = makeExecutableSchema({
  typeDefs: [pictures.typeDef],
  resolvers: merge(
    pictures.resolvers
  ),
});

export default schema;

5. Apollo Server에 Schema 연결

이제 만들어준 schema 파일을 index.js에 import 해오고

주석처리해둔 Apollo Server 코드를 주석해제하여 schema를 연결해준다.

// index.js

import schema from './graphql';


// 주석 해제 및 schema 연결
const apollo = new ApolloServer({
  schema
});

apollo.applyMiddleware({ app });

6. 서버 실행

이제 연결한 서버가 잘 실행되는지 확인하기 위하여 package.json에서 정의해둔 실행 코드를 입력한다.

yarn start:dev

이후 Apollo Server가 잘 연결되었다면, 기본적으로 graphql 엔드포인트에 graphql playground 가 실행되는 것을 확인할 수 있다.

마치며 ...

혹여나 koa와 mongodb, apollo server를 연동하고자 하시는 분들이 계시다면

이 글이 도움이 되시기를 바랍니다. :)

profile
생각하며 코딩하려고 노력하는 개발자가 되겠습니다.

0개의 댓글