RailsとReactをGraphQLでつなぐ

[前回の記事](https://qiita.com/daiki-murakami/items/7a1c4864117bb1a243f0)でdocker-composeを使ってRailsとReactを立ち上げることができたので今回はこれらをGraphQLでつなぐところまでやっていきます！

### Rails側のGraphQL設定
まずはRailsをGraphQLにつなぎます
※Rails側の設定については[こちらの記事](https://qiita.com/dkawabata/items/4fd965ee6d7295386a8b)を参考にさせていただきました

最初にGraphQLのgemをインストールします

```:Gemfile
gem 'graphql'

group :development do
  gem 'graphiql-rails'
end
```
これで一回`bundle install`

GraphQLが入ったので`rails g graphql:install`で必要なファイルが一通り作られます

APIモードでは一部追加されない部分があるので追加します

```ruby:config/route.rb
if Rails.env.development?
  mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: '/graphql'
end
```

```ruby:config/application.rb
require "sprockets/railtie"
```

```javascript:app/assets/config/manifest.js
//= link graphiql/rails/application.css
//= link graphiql/rails/application.js
```

最後にReact側からの接続を有効にするためにapplication.rbに以下を追記します。こちらに関してはまだ理解が足りてないのでまた改めて記事を...！

```ruby:config/application.rb
config.hosts = nil
config.autoloader = :classic
```

これでRails側の設定は完了です！

`docker-compose up -d`をして、`http://localhost:3000/graphiql`にアクセスするとgraphiqlの画面がでてきます

左側に

```
query{
  testField
}
```
と書いて▶ボタンを押してみましょう

右側に

```
{
  "data": {
    "testField": "Hello World!"
  }
}
```
と出てきたら成功です！

![Rails-GraphQL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638400/f028c836-7731-2282-cf69-4fd6cb13b48e.png)

### React側のGraphQL設定
ReactでもGraphQLを設定していきます

まずパッケージのインストールを行います

package.jsonのdependenciesに以下を追加します(バージョンは記事を書いたときのものなので適宜変更をおねがいします)

```
"@apollo/react-hooks": "3.1.5",
"apollo-boost": "0.4.9",
"apollo-client": "^2.6.4",
"graphql": "^14.3.1",
"graphql-tag": "2.10.3",
"react-apollo": "3.1.5",
"react-router-dom": "5.2.0",
```
※apollo-boostは他のもので代用可能です。apollo-boostはカスタマイズ性に乏しいらしいので人によっては使わないほうがいいかもしれないです。詳しくは[こちらの記事](https://gfx.hatenablog.com/entry/2018/10/30/112054)と[ドキュメント](https://www.apollographql.com/docs/react/migrating/boost-migration/)をご覧ください

また、RailsとReactをつなぐためにproxyを使います。

```json:package.json
"proxy": "http://rails:3000"
```
proxyというのは英語で代理人という意味で`http://localhost:4000`に来たリクエストを`http://rails:3000`にそのまま渡します。`rails:3000`というのはdocker-composeで作成したrailsコンテナの3000番ポートのことなのでこれでReactに来たGraphQLのリクエストをRails側に送ることができます

※このようにproxyを設定すると他のパスもすべてRailsに送られてしまうのではないかと思いますがリクエストで送る内容に応じてうまくproxyするものを選んでくれるみたいです(この辺そんなに詳しくないのでちゃんとわかったらまたどこかで書こうと思います)

接続の準備ができたので早速実装していこうと思います

```javascript:src/App.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route } from 'react-router-dom';
import ApolloClient from 'apollo-boost'
import { ApolloProvider } from "@apollo/react-hooks"
import Top from './pages/Top';

const client = new ApolloClient({
  uri: 'http://localhost:4000/graphql'
})

class App extends Component {
  render() {
    return (
      <ApolloProvider client={client} >
        <div className="App">
          <Router>
            <Route exact path='/' component={Top}/>
          </Router>
        </div>
      </ApolloProvider>
    );
  }
}

export default App;
```

```javascript:src/pages/Top.js
import React from 'react';
import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';

const TEST = gql`
  query test {
    testField
  }
`;

export default function Top() {
  const { loading, data } = useQuery(TEST, {});
  if (loading) return <p>Loading ...</p>;
  return <h1>{data.testField}</h1>;
}
```

これで設定は完了です！`docker-compose up -d`して`http://localhost:4000`にアクセスしてみましょう。下の画面のようにでてくれば成功です！

![React-GraphQL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638400/8980b18c-d3e6-155d-9c02-63ac77d97d29.png)

以上でGraphQLでRailsとReactをつなぐ方法は終わりです！

まだまだ細かいところで理解不足なところが多いのでそこは引き続き勉強して拡充していければと思います