【基礎の基礎編】React + Express + GraphQLでHello World!


はじめに

この記事は、GraphQLの基礎の基礎として、サーバーサイドとクライアントサイドを最低限実装し、GraphQLで接続する機能を実装しています。データの更新や、DB接続してデータを取得したりなどは行っていません。GraphQLでクライアントとサーバーの連携の概要を理解していただければと思います。

source

GraphQLとは

GraphQLはAPIのための問い合わせ言語です。クエリを実行してデータを呼び出すためのランタイムをさすこともあります。

GraphQLの問い合わせ言語

GraphQLは、データベースに問い合わせるために開発されたSQLの考え方をインターネットに適用したものです。単一のGraphQLのクエリを使い、関連するデータをまとめて取得できます。また、データを変更したり削除したりすることもできます。SQLとGraphQLは問い合わせ言語という点で共通しています。

ただ、どちらも問い合わせ言語ではあるものの、GraphQLとSQLは全く異なるものです。

  • SQLのクエリはデータベースに対して実行される(データベースのための問い合わせ言語)
  • GraphQLのクエリはAPIに対して実行される(インターネットのための問い合わせ言語)

構文

  • SQL: SELECT, GraphQL: Query
  • SQL: INSERT/UPDATE/DELETE, GraphQL: Mutation

GraphQLはインターネットのための問い合わせ言語なので、ソケット通信を使ってデータの変更を監視するためのコマンドも用意されている。そのコマンドを"Subscription"と呼びます。

GraphQLサーバーの実装

まず、サーバーサイドとして、簡単な(Hello Worldを表示する)APIを作成してみましょう。
今回はApollo ServerはOSSで、非常にシンプルにセットアップできる上、本番環境に投入できる水準の機能を多く提供しています。
代表的な機能としては、サブスクリプションのサポート、ファイルのアップロード、既存のサービスのAPIからデータを取得する機能、クラウドサービスのApollo Engineがあります。

環境構築

ディレクトリ構成

myappServer/
  ├ node_modules
  ├ src
    ├ resolbers
      ├ index.js
      └ Query.js
    ├ index.js
    └ typeDefs.graphql
  └ package.json 
$ npm init -y // 初期化処理
$ npm install express apollo-server-express graphql-playground-middleware-express // モジュールのインストール

プログラム

index.js
const express = require("express");
const { ApolloServer } = require('apollo-server-express');
const { readFileSync } = require('fs');
const resolvers = require('./resolvers');

const typeDefs = readFileSync('./src/typeDefs.graphql', 'utf-8');

const app = express();

const server = new ApolloServer({typeDefs, resolvers});

server.applyMiddleware({ app })

app.get('/', (req, res) => res.end(`Welcome to the PhotoShare API`))

app.listen({ port: 4000 }, () => console.log(`GraphQL Server runnning @ http://localhost:4000{server.graphqlPath}`))
typeDefs.graphql
type Query {
    helloWorld: String!
}
resolvers/index.js
const Query = require('./Query');

const resolvers = {
    Query
}

module.exports = resolvers
resolvers/Query.js
module.exports = {
    helloWorld: () => 'Hello World'
}

サーバーの起動

$ cd myappServer
$ node src/index.js

>>>
GraphQL Server runnning @ http://localhost:4000{server.graphqlPath}

GraphQL Playgroundで実行してみましょう。

GraphQLクライアントの実装

次に、先ほど作成したGraphQLサーバーにクライアントからアクセスしてみましょう。

reactプロジェクトの作成

$ create-react-app myappClient

インストール

$ npm install graphql graphql-request
  • graphql-request

GraphQLオペレーションをAPIに送信するために利用できるフレームワークがいくつか存在します。その中で有名な"graphql-request"を使用します。これはfetchリクエストをPromiseでラップして、GraphQLサーバーへのリクエストを送信します。また、リクエストの構築とデータのパースに関する細かい処理を引き受けます。

プログラム

作成されたApp.jsを下記のように書き換えてください。

App.js
import { useState } from 'react';
import './App.css';
import { request } from 'graphql-request'

const url = 'http://localhost:4000/graphql'

const query = `
  query helloWorld {
    helloWorld
  }
`

function App() {
  const [hello, setHello] = useState('');

  const graphQL = async () => {
    const result = await request(url, query)
    setHello(result.helloWorld)
  }

  return (
    <div className="App">
      <button onClick={graphQL}>Click</button>
      <div>{hello}</div>
    </div>
  );
}

export default App;

request()でurlとqueryを引数として受け取ってサーバーへのリクエストを構築して、結果のデータを返します。ここでレスポンスされるデータは期待した通りのJSONデータ { "helloWorld": "Hello World" } がレスポンスされます。

サーバーの起動

$ cd myappClient
$ npm start

サーバーが起動したら、ブラウザが立ち上がり、「click」ボタンをクリックすると「Hello World!」と表示されるはずです。