1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Node.js × Expressで始めるGraphQL入門

Last updated at Posted at 2021-01-17

概要

GraphQLを初めて実装してみた時の手順と、サンプルソースコードを記載しています。

環境

  • macOS Big Sur 11.1
  • node v14.12.0
  • yarn 1.22.10
  • express 4.16.1
  • Docker version 19.03.13
  • docker-compose version 1.27.4

サンプルソースコード

hayatoiwashita/express-graphql

手順

1. プロジェクトの雛形を作成

express-generatorを使用した。
--gitオプションは.gitignoreを追加するためのオプション。

$ express --view=pug --git express-graphql

参考: Express のアプリケーション生成プログラム

2. ライブラリのインストール

GraphQL関連のライブラリは最低限下記があればOK。

$ yarn add graphql
$ yarn add express-graphql

サンプルでは下記も追加している(本題から逸れるので割愛)

# ホットリロード
$ yarn add --dev nodemon
# コード整形
$ yarn add prettier --dev --exact
$ yarn add eslint --dev
$ yarn add --dev eslint-config-prettier
$ yarn add --dev eslint-plugin-prettier
# commit時にコード整形を実行
$ yarn add --dev lint-staged
$ yarn add --dev husky

3. サンプルデータの用意

/data/users.jsを追加して、DBの代わりに使用した。
(内容はサンプルソースコードのusers.jsを参照)

4. schemaを定義

/schema/schema.graphqlを作成してschemaを定義。
今回は参照系クエリのみ実装した。
データ構造は、ユーザとそれに紐づく投稿といった形。

schema.graphql
const { buildSchema } = require("graphql");

const schema = buildSchema(`
    type Query {
        users: [User!]!,
        user(id: Int!): User!
    }

    type User {
        id: ID!
        name: String!
        email: String
        posts: [Post!]
    }

    type Post {
        id: ID!
        title: String!
        published: Boolean!
        link: String
        author: User!
    }
`);

module.exports = schema;

5. リゾルバを作成

データ操作を行う/src/resolvers.jsを作成。
上述の通り、今回は参照系のみ。

resolvers.js
const { Users } = require('../data/users');

const resolvers = {
  users: async (_) => {
    console.log('come here');
    return Users;
  },
  user: async ({ id }, context) => {
    return Users.find((user) => user.id == id);
  },
};

module.exports = resolvers;

6. app.js を修正

エンドポイント/graphqlを定義。

app.js
// var createError = require('http-errors');
var express = require('express');
var { graphqlHTTP } = require('express-graphql');
var resolvers = require('./src/resolvers');
var schema = require('./schema/schema.graphql');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(
  '/graphql',
  graphqlHTTP({
    schema,
    rootValue: resolvers,
    graphiql: true,
  })
);

module.exports = app;

7. [参考] コンテナ化

Dockerfiledocker-compose.ymlを追加。

FROM node:14.15.4-slim

WORKDIR /usr/local/src/express-graphql
ADD . .
RUN yarn install
CMD [ "yarn", "start" ]
docker-compose.yml
version: '3'

services:
  graphql:
    build: .
    container_name: graphql-container
    ports:
      - "3000:3000"

8. Expressの起動

起動コマンドを実行。

# コンテナで実行
$ docker-compose up

# コンテナを使用せず実行
$ yarn start

9. クエリを実行

http://localhost:3000/graphql をブラウザで開く。
screencapture-localhost-3000-graphql-2021-01-16-16_08_50.png

サンプルクエリ
内容としては、ユーザID=1のユーザの名前と、そのユーザの投稿(posts)のIDとタイトルを取得するというもの。

{
  user(id:1) {
    name
    posts {
      id
      title
    }
  }
}

実行結果

{
  "data": {
    "user": {
      "name": "Fikayo Adepoju",
      "posts": [
        {
          "id": "1",
          "title": "Debugging an Ionic Android App Using Chrome Dev Tools"
        },
        {
          "id": "2",
          "title": "Hosting a Laravel Application on Azure Web App"
        }
      ]
    }
  }
}

screencapture-localhost-3000-graphql-2021-01-17-15_09_38.png

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?