본문 바로가기

개발/부록

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

반응형

 

시작하며 ...

요즘 공부하는 것중 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를 연동하고자 하시는 분들이 계시다면

 

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

반응형

'개발 > 부록' 카테고리의 다른 글

What is REST API  (0) 2020.04.22
GraphQL로 Redux Local 동작 대체하기  (0) 2020.04.21
[부록] Shallow Merge VS Deep Merge  (0) 2020.04.18
[부록] Cookie, Web Storage  (0) 2020.04.17
Ctrl +Z, Ctrl +C in Linux  (0) 2020.04.13