Express + mongoDB를 사용하여 GraphQL 서버 구축 (on docker-compose)

개요


  • GraphQL의 구축을 배웠으므로, 복습으로서 기사로 해 보았다
  • 이 기사에서는 절차 만 설명하고 자세한 내용은 설명하지 않습니다.
  • 이 기사의 목표는 로컬에서 GraphiQL을 시작하고 거기에서 쿼리를 실행하여 데이터를 검색하는 것입니다.
  • htps : // 기주 b. 이 m / Mr 후쿠 / 에 xp 렛 s-g 등 phql - r ゔ ぇ r

  • 환경


  • Mac OS Mojave
  • docker-compose 1.25.4
  • Node.js 14.2
  • express 4.17.1
  • graphql 15.0.0
  • MongoDB 4.2.6

  • 【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을 사용한 칸방 앱 작성 기사도 작성 예정입니다.

    좋은 웹페이지 즐겨찾기