Express + mongoDB를 사용하여 GraphQL 서버 구축 (on docker-compose)
개요
환경
【1】프로젝트의 작업 디렉토리를 작성, 이동
mkdir
에서 디렉토리를 만들고 cd
로 이동$ mkdir express-graphql-server
$ cd express-graphql-server
【2】docker-compose.yml을 작성, mongoDB의 기동
docker-compose.yml
version: '3'
services:
mongo:
image: mongo
restart: always
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
volumes:
- ./db/db:/data/db
- ./db/configdb:/data/configdb
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
depends_on:
- mongo
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: example
# http://localhost:8081 で Mongo Express が起動
$ docker-compose up

【3】express의 기동
server 디렉토리를 만들고 server/Dockerfile을 만듭니다.
server/Dockerfile
FROM node:14.2-alpine3.11
WORKDIR /server
RUN apk update
COPY . .
# 後にコメントを外す
# COPY package.json ./
# COPY yarn.lock ./
# RUN yarn install
docker-compose.yml에 server 컨테이너 추가
docker-compose.yml
version: '3'
services:
# serverコンテナを追加
server:
build: ./server
tty: true
ports:
- 4000:4000
volumes:
- ./server/:/server
- /server/node_modules
depends_on:
- mongo
mongo:
image: mongo
restart: always
ports:
...
서버 컨테이너를 시작하고 컨테이너 내에 필요한 패키지를 설치합니다.
# serverコンテナを立ち上げ、shellを起動する
docker-compose run server sh
# yarnで今回必要となるpackage一式をインストールします
yarn add express express-graphql graphql mongoose nodemon
# コンテナから抜ける
exit
server/Dockerfile을 다음과 같이 다시 작성하고 docker-compose.yml에 command를 추가합니다.
server/Dockerfile
FROM node:14.2-alpine3.11
WORKDIR /server
RUN apk update
# コメントアウト
# COPY . .
# コメントを外す
COPY package.json ./
COPY yarn.lock ./
RUN yarn install
docker-compose.yml
version: '3'
services:
server:
build: ./server
tty: true
ports:
- 4000:4000
volumes:
- ./server/:/server
- /server/node_modules
depends_on:
- mongo
command: yarn nodemon app # <- express起動用のcommandを追加
mongo:
image: mongo
restart: always
ports:
...
server/app.js를 만들고 docker의 컨테이너 이미지를 다시 빌드합니다.
다시 컨테이너를 시작하고 express가 시작되는지 확인합시다.
server/app.js
const express = require('express')
const app = express()
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(4000, () => console.log('Example app listening on port 4000!'))
# http://localhost:4000 を開いて「Hello World!」と表示される
docker-compose build
docker-compose up
【4】mongoDB에 테스트용 데이터베이스의 작성
브라우저에서 http://localhost:8081에 액세스하면 Mongo Express가 표시되므로,
이미지와 같이 입력하여 'test'라는 데이터베이스를 만듭니다.

또한 test 데이터베이스에 'books'라는 collection을 추가하고 테스트를 위한 데이터를 하나씩 만듭니다.


그런 다음 테스트 데이터베이스를 조작하기위한 사용자를 만듭니다.
사용자 이름과 비밀번호는 나중에 사용하므로 메모해 둡시다.
# 起動中のmongoコンテナ内に入り、shellを起動
docker-compose exec mongo sh
# root権限でmongoシェルを起動
mongo -u root -p example
# createUserコマンドでtestデータベースを読み書きできるユーザーを作成
db.createUser({ user: "user", pwd: "password", roles: [{ role: "readWrite", db: "test" }]})
# mongoシェルから抜ける
exit
# mongoコンテナから抜ける
exit
【5】mongoDB와의 접속
server/app.js를 다음과 같이 다시 작성하고 서버 시작시 콘솔에 "connected mongoDB"라고 표시되면 연결 성공입니다.
server/app.js
const express = require('express')
const app = express()
+ const mongoose = require('mongoose')
+
+ const user = 'user'
+ const pass = 'password'
+ mongoose.connect(`mongodb://${user}:${pass}@mongo/test`)
+ mongoose.connection.once('open', () => {
+ console.log('connected mongoDB')
+ })
app.get('/', (req, res) => res.send('Hello World!'))
app.listen(4000, () => console.log('Example app listening on port 4000!'))

【6】graphql 스키마의 정의
server/models/book.js
를 만들고 book 모델을 정의합니다.server/models/book.js
const mongoose = require('mongoose')
const Schema = mongoose.Schema
// nameというフィールドを持つbookモデルを定義
const bookSchema = new Schema({
name: String,
})
module.exports = mongoose.model('Book', bookSchema)
server/schema/schema.js
를 만들고 스키마를 정의합니다.server/schema/schema.js
const graphql = require('graphql')
const Book = require('../models/book')
const { GraphQLSchema, GraphQLObjectType, GraphQLID, GraphQLString } = graphql
const BookType = new GraphQLObjectType({
name: 'Book',
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
}),
})
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
// idを引数に対象レコードを返すbookクエリを定義
book: {
type: BookType,
args: { id: { type: GraphQLID } },
resolve(_, args) {
return Book.findById(args.id)
},
},
},
})
module.exports = new GraphQLSchema({
query: RootQuery,
})
마지막으로
server/app.js
에 graphql 엔드 포인트 정의를 추가하면 완성됩니다!server/app.js
const express = require('express')
const mongoose = require('mongoose')
+ const graphqlHTTP = require('express-graphql')
+ const schema = require('./schema/schema')
const app = express()
const user = 'user'
const pass = 'password'
mongoose.connect(`mongodb://${user}:${pass}@mongo/test`)
mongoose.connection.once('open', () => {
console.log('connected mongoDB')
})
app.get('/', (req, res) => res.send('Hello World!'))
+ app.use('/graphql', graphqlHTTP({
+ schema,
+ graphiql: true,
+ })
+ )
app.listen(4000, () => console.log('Example app listening on port 4000!'))
http://localhost:4000/graphql
에 액세스하면 GraphiQL이 시작되어야합니다.
book 쿼리를 두드려 방금 추가한 데이터가 반환되면 OK입니다! (수고하셨습니다)

가까운 장래에 GraphQL을 사용한 칸방 앱 작성 기사도 작성 예정입니다.
Reference
이 문제에 관하여(Express + mongoDB를 사용하여 GraphQL 서버 구축 (on docker-compose)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/iPzYN2gLSV2HeSS/items/ee4487c6d67993ecf429텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)