使用Express和MongoDB在docker-compose上构建GraphQL服务器
总结
-
- GraphQLの構築を学んだので、復習として記事にしてみた
-
- この記事では手順のみを記載し、詳細は説明しない
-
- この記事のゴールとしてはローカル上でGraphiQLを起動し、そこでクエリを実行しデータを取得するところ
- https://github.com/MrFuku/express-graphql-server
生態圈
-
- Mac OS Mojave
-
- docker-compose 1.25.4
-
- Node.js 14.2
-
- express 4.17.1
-
- graphql 15.0.0
- MongoDB 4.2.6
创建并切换到项目工作目录。
使用mkdir命令来创建目录,并使用cd命令进行移动。
$ mkdir express-graphql-server
$ cd express-graphql-server
创建docker-compose.yml文件,启动mongoDB。
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文件。
FROM node:14.2-alpine3.11
WORKDIR /server
RUN apk update
COPY . .
# 後にコメントを外す
# COPY package.json ./
# COPY yarn.lock ./
# RUN yarn install
将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
将服务器/Dockerfile按以下方式修改,并在docker-compose.yml中添加命令。
FROM node:14.2-alpine3.11
WORKDIR /server
RUN apk update
# コメントアウト
# COPY . .
# コメントを外す
COPY package.json ./
COPY yarn.lock ./
RUN yarn install
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是否成功启动。
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にテスト用データベースの作成



然后,我们创建一个用于操作test数据库的用户。
请记下用户名和密码,稍后会用到。
# 起動中の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」と表示されれば接続成功です
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模型。
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文件,并定义架构。
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 终点的定义,那么就完成了!
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。

请查询书籍,如果刚刚添加的数据返回了,那就好了!(辛苦了)

不久的将来,我计划撰写一篇使用GraphQL创建看板应用程序的文章。