はじめに
GraphQL使ってみたいなぁ。調べたところ、GraphQLをサーバーサイドで実装しているのはRubyとnodejs。検索結果の量で比べるとnodejsの方が多い。とくにApollo を使った記事が多い。
ということで、サーバーサイドはApolloでGraphQLを実装し、フロントもApollo Clientで、と行きたいところなのですが、私が調べて実際使ってみたところ、Apollo Client+Reactは色々制約があって使いづらい。もう少し突っ込んで調べたところ、GraphQLサーバーに QueryとMutaionのリクエストを行える、graphql-requestという npmパッケージがあるのを見つけた。これを実際使ってみると、結構なレベルで思い通りにプログラミングできるようになったので、以下の組み合わせでGraphQLの練習として、商品マスターメンテナンスを組んでみたいと思う。
サーバーサイド Apollo Server + GraphQL + nodejs + sequelize
フロントエンド React + Redux + graphql-request
RESTと何かと比較され、RESTの次世代のGraphQLだと言われますが、実際にその正体を突き止められることを目指しています。私も、最初コーディングしてるときは、ちんぷんかんぷんでしたが、わかりだすとするすると理解が進みますし、GraphQLの良さも体感できます。
かなり長いですが、我慢してお付き合いください。
結構なボリュームなので、4回か5回に分けての連載になります。
・第1回 Apollo Serverが動くところまで(この記事)
・第2回 Apollo Server配下で、GraphQLを使って商品マスターにアクセスする
・第3回 フロントエンドをReact+Redux+graphql-requestを使って実装する
・第4回 フロントエンドからgraphql-requestを使って、データを取得・表示する
・第5回 graphql-requestを使って、データを登録・修正・削除する
まず、第一回はサーバーサイドのプロジェクトを作り、必要なnpm パッケージを導入し、
npm startで Apollo Serverが動くところまで。
ファイルの構成がわかりにくいと思うので、完成形のフォルダ構成を示しておきます。

サーバーサイドの準備
まずは開発フォルダを作成します。
[bash]
$ mkdir ~/workspace
$ mkdir ~/workspace/graphql-master
$ mkdir ~/workspace/graphql-master/server
$ cd ~/workspace/graphql-master/server
[/bash]
npmを使って、必要なパッケージ群をインストール
[bash]
$ npm init -y
$ npm install –save apollo-datasource apollo-server dotenv graphql nodemon pg sequelize
$ npm install –save-dev apollo apollo-link apollo-link-http babel-cli babel-plugin-transform-object-rest-spread babel-preset-env jest nock node-fetch
[/bash]
Apollo Serverを起動させるために
サーバーサイドの中心となるファイル index.jsにApollo Serverを起動するための、あれこれを記述していきます。
以下、コンソールで、コマンドを記述してあるのは、基本、 プロジェクトルート/src ディレクトリをベースに記載します。
[bash]
$ mkdir src
$ cd src
$ nano index.js
[/bash]
index.js (src/index.js)
いろんなファイルをインクルードしていきます。これらのファイルはApollo ServerでGraphQLを動かすのに、必須なファイル群です。最初は意味がわからなくても、あぁ、こんなファイルがいるんだなと、感覚的に覚えるようにしてください。
schema というのは、GraphQL APIの定義を書く場所です。
resolvers というのは、schema に記述したAPIの実装を書く場所です。
store というのは mysqlやpostgresql のデータストアの定義を書く場所です。
dataSources というのは、データベースの各テーブルに対するモデルをまとめるためのものです。
最後に server.listenで、nodejs サーバー(Apollo Server)を起動しています。
[bash]
import {ApolloServer} from “apollo-server”;
import typeDefs from “./schema”;
import resolvers from “./resolvers”;
import { createStore } from “./store”;
const path = require(‘path’);
require(‘dotenv’).config({ path: path.join(__dirname, ‘../.env’) });
const store = createStore();
const dataSources = () => ({
productAPI: new ProductAPI({store}),
});
const server = new ApolloServer({
typeDefs,
resolvers,
},
context: async({req}) => {
return {
SECRET: process.env.SECRET,
}
},
dataSources,
});
server.listen().then(({ url }) => {
console.log(`GraphQL マスターメンテナンス Server ready at ${url}`);
});
[/bash]
.env(.env)
環境設定ファイルに、データベースへの接続設定とシークレットキーを定義します。
[bash]
$ nano ../.env
[/bash]
[bash]
DATABASE=graphql_dev
DATABASE_USER=postgres
DATABASE_PASSWORD=mypass
SECRET=xz5y78fwfwefwekwfhyu.1856547.ffgxmz
[/bash]
このファイルはお決まりの魔法の言葉だ程度で覚えておいて、とりあえず、作ってください。
[bash]
$ nano ../.babelrc
[/bash]
[bash]
{
“presets”: [
[
“env”, {
“targets”: {
“node”: “current”
}
}
]
],
“plugins”: [“transform-object-rest-spread”]
}
[/bash]
schema.js (src/schema.js)
では GraphQL APIの定義を書いていく schema.jsです。
[bash]
$ nano schema.js
[/bash]
とりあえず、Query と Mutationは 適当なものでごまかしておきます。(あとで修正します)
[bash]
import { gql } from “apollo-server”;
export default gql`
type Query {
getProduct(id: Int!): Int!
}
type Mutation{
registerProduct(id: Int!): Int!
}
`;
[/bash]
resolvers.js (src/resolvers.js)
では GraphQL APIの実装を書いていく resolvers.jsです。
とりあえず、空っぽの Query と Mutationを定義しておきましょう。
[bash]
$ nano resolver.js
[/bash]
[bash]
import { ForbiddenError } from ‘apollo-server’;
export default {
Query: {
},
Mutation: {
}
}
[/bash]
store.js (src/store.js)
データベースへの接続と、実際に使うテーブルのスキーマを記述します。
[bash]
$ nano store.js
[/bash]
[bash]
import SQL from “sequelize”;
export const createStore = () => {
const db = new SQL(process.env.DATABASE, process.env.DATABASE_USER, process.env.DATABASE_PASSWORD, {
dialect: “postgresql”,
});
const products = db.define(‘product’, {
id: {
type: SQL.INTEGER,
primaryKey: true,
autoIncrement: true,
},
product_name: {
type: SQL.STRING,
allowNull: false,
},
price: {
type: SQL.INTEGER,
allowNull: false,
},
createdAt: {
type: SQL.DATE,
},
updatedAt: {
type: SQL.DATE,
},
});
return { products };
}
[/bash]
Apollo Server起動
package.jsonを使って npm start で、Apollo Server(nodejs)を動かせるようにします。
babel-node というのは ES2015形式で書いた新しい形式のソースを、古い形式に変換するためのものです。
[bash]
$ nano ../package.json
[/absh]
[bash]
“scripts”: {
“start”: “nodemon –exec babel-node src/index.js”,
“build-prod”: “babel src -d dist”,
“build”: “babel src -d build/ –source-maps”,
“serve”: “node dist/index.js”,
“test”: “echo \”Error: no test specified\” && exit 1″
},
[/bash]
では、Apollo Serverを起動してみましょう。
[bash]
$ npm start
[/bash]
こんな感じに表示されたら、とりあえず、Apollo Serverが動いています。

Leave a comment