GraphCMSでApolloClient3.0に入門してみた 

##成果物

本当にただのポートフォリオ（カメラ的な意味で）
https://cranky-swirles-e2bc61.netlify.app/
https://github.com/tkeshiino21/each-life

##TL;DR

フロントエンドエンジニアがApolloClientに入門するのに、
graphCMSは案外けっこういいかもしれないという話。

##GraphCMSとは

Contentfulみたいなやーつです。
HeadlessContentsManagementSystemといって、VIEWのないWordPress的なものだと想像してもらえればいいかと。ブログ投稿機能的なものです。
で、このGraphCMSなんですが、名前からもお察っしの通りgraphQLに特化したCMSでして、graphQLとかApolloちょっと触ってみたいよ！って方にぴったりなんじゃないかと思い、今回ご紹介します。

##GraphCMSは何がおいしいのか？

GraphQLを使って何かサービスを作ってみよう！と思いたったときに、
フロントエンドエンジニアにとって、いきなりApolloServerとかHasuraはちょいと難しいです。
ぶっちゃけ私は挫折しました。
ということで、一旦GraphCMSで素振りしようと使ってみたらなかなか良かったです。
GUIだけでバックエンドの側が完了してしまう感じでした。

また、GraphQLやApollo自体の利点については以下がめっちゃ良い記事ですのでぜひ。
[世のフロントエンドエンジニアにApollo Clientを布教したい](https://qiita.com/seya/items/26c8a0dc549a10efcdf8)

##GraphCMSをはじめてみる

https://graphcms.com/docs/guides/quickstart

ログインしてクイックスタートします。
BlogStarterなど、最初から入っているテンプレートを使うとスムーズです。



↓こんな感じです。

1.SchemaというgraphQLにおける型みたいなものを定義する
<img width="1118" alt="スクリーンショット 2020-06-14 23.31.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487370/e9f16bcf-6304-43a0-b5a5-3d185bde1f45.png">

2.投稿してみる
<img width="1096" alt="スクリーンショット 2020-06-14 23.27.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487370/0c28670f-db7a-aa25-4d1f-11d4c27a78d0.png">

3.APIPlayGroundでQueryを書いて投げてみる
左側に書いて▶で右側にレスポンスが表示されます。
<img width="1118" alt="スクリーンショット 2020-06-14 23.33.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487370/2aa177c4-8ef4-0a77-04fc-430b61b4df99.png">

##Reactにつなぐ

今回はβ版の3.0を使ってみます。

``` react
import React from 'react';
import ReactDOM from 'react-dom';
import {
  ApolloProvider,
  ApolloClient,
  HttpLink,
  InMemoryCache,
} from '@apollo/client';
import App from './App';

const GRAPHCMS_API =
  'https://api-ap-northeast-1.graphcms.com/v2/YOUR_API_KEY/master';

const client = new ApolloClient({
  link: new HttpLink({ uri: GRAPHCMS_API }),
  cache: new InMemoryCache(),
});

ReactDOM.render(
  <React.StrictMode>
    <ApolloProvider client={client}>
      <App />
    </ApolloProvider>
  </React.StrictMode>,
  document.getElementById('root'),
);
```

って感じです。
[ApolloDevTools](https://chrome.google.com/webstore/detail/apollo-client-developer-t/jdkknkkbebbapilgoeccciglkfbmbnfm)で↓のように右側に何かしらQueryが表示されていたらReactへの繋ぎこみは成功です。

<img width="994" alt="スクリーンショット 2020-06-14 22.57.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487370/82e2c547-68b3-8499-1298-a35370f7cd33.png">

##Queryを書く

ここまで行ったら、先ほどのAPIplaygroundでレスポンスが通ったコードをコピペして、
gqlのタグではさんでください。↓こんな感じです。

``` react
import { gql } from '@apollo/client';

export const GET_PHOTOS = gql`
  query GetPhotos {
    photos {
      id
      image {
        id
        url
      }
      caption
      updatedAt
    }
  }
`;
```

##ApolloのHooksを使う

あとはAPIを叩くだけです。
[Apolloの公式ドキュメント](https://www.apollographql.com/docs/react/v3.0-beta/api/react/hooks/)を参考にしました。
HOCでも良いですが、↓のようなHooksの方がより簡潔になるのでオススメです。

``` react

import React, { FC } from 'react';
import { GET_PHOTOS } from './graphql/queries'
import { Loader } from '../atoms'
 
const Photos: FC = () => {
  const { loading, error, data } = useQuery(GET_PHOTOS);

  if (loading) return <Loader />;
  if (error) return <p>err</p>;

  return (
    ...省略...
  );
};

export default Photos;
```

ね、簡単でしょう！

##おまけ

GraphQLのSchemaからTypeScriptの型を自動生成してくれる、
graph-codegenという超絶素晴らしいライブラリがあります。
使い方は下記の中西さんの動画をご覧ください。

[Apollo × TypeScript で型安全なフロントエンドを開発する](https://www.youtube.com/watch?v=eEJihLxMFu8)

ApolloClient3.0の場合、codegen.ymlは↓のようになるかと思います。
（ここはザルなので違ってたらすみません）

``` yml
overwrite: true
schema: 'https://api-ap-northeast-1.graphcms.com/v2/YOUR_API/master'
documents: 'src/gql/**.ts'
generates:
  src/generated/graphql.tsx:
    plugins:
      - 'typescript'
      - 'typescript-operations'
      - 'typescript-react-apollo'
    config:
      reactApolloVersion: 3
      withHooks: true
      withHOC: false
      withComponent: false
      gqlImport: '@apollo/client#gql'
      apolloReactCommonImportFrom: '@apollo/client'
      apolloReactComponentsImportFrom: '@apollo/client'
      apolloReactHocImportFrom: '@apollo/client'
      apolloReactHooksImportFrom: '@apollo/client'
  ./graphql.schema.json:
    plugins:
      - 'introspection'
```


ちなみにこれを使うと先程のコードは↓のようになります。

``` react

import React, { FC } from 'react';
import { useGetPhotosQuery } from '../../generated/graphql';
 
const Photos: FC = () => {
   const { loading, error, data } = useGetPhotosQuery();

  if (loading) return <Loader />;
  if (error) return <p>err</p>;

  return (
    ...省略...
  );
};

export default Photos;
```

うひょーー、めっちゃシンプル！
これで型がついているので補完が効きますし、
変なコードを書くとその都度叱ってくれるので、便利すぎて禿げるレベルです。

##まとめ

以上、graphCMSのご紹介とApolloの入門でした。
graphql-codegenも合わせて使うと最高のDXを得られるので、ぜひお試しください。

最後まで読んでいただきありがとうございました！