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

![graphql-1200x630-960x504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618885/ed88920d-72c2-2d9a-b3b4-0aad2057c8e4.png)

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

### source
https://github.com/kyokozuka/react-node-express-graphql

# GraphQLとは
[GraphQL](https://graphql.org/)はAPIのための問い合わせ言語です。クエリを実行してデータを呼び出すためのランタイムをさすこともあります。

# GraphQLの問い合わせ言語
GraphQLは、データベースに問い合わせるために開発されたSQLの考え方をインターネットに適用したものです。単一のGraphQLのクエリを使い、関連するデータをまとめて取得できます。また、データを変更したり削除したりすることもできます。SQLとGraphQLは問い合わせ言語という点で共通しています。<br />
ただ、どちらも問い合わせ言語ではあるものの、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で実行してみましょう。
![スクリーンショット 2021-01-14 171105.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618885/b812fe14-083e-1949-7d39-2089cdaa5a1c.png)

# 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!」と表示されるはずです。

![スクリーンショット 2021-01-14 172910.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618885/ab74e00f-224d-f6e9-5027-a09fbb7b3acb.png)