시작하며 ...
요즘 공부하는 것중 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 |