今後のトレンドになるgraphqlでのWEBアプリを作ってみたかった。業務(仕事)でやらしてくれるはずがなかった。
諦めて自分でWEBアプリを作ることにした。
いきなりはできないので、すでに立っているgraphqlサーバーを利用する事にしました。
それはgithubです
5年前ぐらいに対応した・・・みたいな事を書いてあった。
またudemmyの学習でも利用しているのでそちらをベースにしました
謝罪
この記事は
の丸パクリに近いです。
ほぼ自分用にメモとして残しています
違いについてはgraphqlのclientの接続部分は別ファイルにしたかったので別にしている
事前作業
プログラムを組む前に色々とやる事がありました
github tokenの作成
githubのAPIにアクセスするにはtokenが必要です。
下記のページにアクセスして
https://github.com/settings/tokens
→ Generate new tokenを押してtokenを作成します
このtokenは基本的は公開しないものです。1回表示したあとに再度表示する事はできない。
scopeに関してはセキュリティを考慮して設定する感じです。
ApolloClientのインストール
graphqlサーバーにアクセスするためには3つの機能が必要です。
- ApolloClient
- ApolloProvider
- InMemoryCache
一昔前だと1つ1つインストールする必要があったのですが、2020/11/03現在では下記の1つでOK
npm install @apollo/client'
プログラムについて
- App.js(メインのプログラム)
- client.js(graphqlのクライアントの設定などしているプログラム)
- Issues.js(graphqlのクエリーを発行している部分)
- .env.development.local(環境変数を設定しているプログラム)
App.js
import React from 'react'; import {ApolloProvider} from '@apollo/client'; import client from './client' import {Issues} from './Issues'; function App() { return ( <> <div className="App"> hello,world </div> <ApolloProvider client={client}> <Issues /> </ApolloProvider> </> ); } export default App;
- ApolloProviderのタグが味噌かな。この範囲にある接続情報を設定している。
ApolloクライアントをApolloProviderコンポーネントとReactに接続します。
ApolloProviderはReactのに似ていContext.Providerます。Reactアプリをラップし、クライアントをコンテキストに配置します。これにより、コンポーネントツリーのどこからでもアクセスできるようになります
https://www.apollographql.com/docs/react/get-started/
公式のサンプルsourceは
import React from "react"; import { render } from "react-dom"; import { ApolloClient, InMemoryCache, ApolloProvider, useQuery, gql } from "@apollo/client"; const client = new ApolloClient({ uri: "https://48p1r2roz4.sse.codesandbox.io", cache: new InMemoryCache() }); function ExchangeRates() { const { loading, error, data } = useQuery(gql` { rates(currency: "USD") { currency rate } } `); if (loading) return <p>Loading...</p>; if (error) return <p>Error :(</p>; return data.rates.map(({ currency, rate }) => ( <div key={currency}> <p> {currency}: {rate} </p> </div> )); } function App() { return ( <ApolloProvider client={client}> <div> <h2>My first Apollo app 🚀</h2> <ExchangeRates /> </div> </ApolloProvider> ); } render(<App />, document.getElementById("root"));
このsourceはわかりにくい・・・というか他に展開しにくい。
- Issuesでクエリーを発行している
今後はpropsでクエリーの内容を変えれるようにしたい
client.js
import {ApolloClient, InMemoryCache} from '@apollo/client'; const GITHUB_TOKEN = process.env.REACT_APP_GITHUB_TOKEN console.log(GITHUB_TOKEN) // GraphQL クライアントを生成 const client = new ApolloClient({ uri: 'https://api.github.com/graphql', headers: {authorization: `Bearer ${GITHUB_TOKEN}`}, cache: new InMemoryCache(), }); export default client;
- uriの部分がgraphqlのエンドポイントになります。
- headersでgithubのtokenを設定しています
- 「cache: new InMemoryCache()」はお決まりみたいな感じで書いています。 下記のパターンの場合はoptionsを設定する
- カスタム主キーフィールドを指定する
- 個々のフィールドの保存と取得をカスタマイズします
- フィールド引数の解釈をカスタマイズする
- フラグメントマッチングのスーパータイプとサブタイプの関係を定義する
- ページネーションのパターンを定義する
- クライアント側のローカル状態を管理する
詳しくはこちら
https://www.apollographql.com/docs/react/caching/cache-configuration/
Issues.js
import * as React from 'react'; import {gql, useQuery} from '@apollo/client'; // 発行する GraphQL クエリ const GET_ISSUES = gql` query { search(query: "repo:apollographql/apollo is:issue", type: ISSUE, first: 5) { issueCount nodes { ... on Issue { number title } } } } `; export const Issues: React.FC = () => { // GraphQL のクエリを実行 const {loading, error, data} = useQuery(GET_ISSUES); // クエリ実行中の表示 if (loading) return <p>Loading ...</p>; // エラー発生時(レスポンスがないとき)の表示 if (error) return <p style={{color: 'red'}}>{error.message}</p>; // クエリの結果が返ってきたときの表示 const {issueCount, nodes: issues} = data.search; return <> <h2>Num of issues: {issueCount}</h2> <ul> { issues.map(i => <li key={i.number}>{i.number} - {i.title}</li>) } </ul> </>; };
loading, error, dataはお決まりみたい・・・。通常のjavascriptで組むと大変なんだような〜。本当に技術の革新に感謝。
.env.development.local
//(40バイトのランダム文字列)
REACT_APP_GITHUB_TOKEN=a1025xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
環境変数は必ず「REACT_APP_」を最初につけないといけない決まりがあるみたい
実際のsourceについて
たぶんcloneすればいける。
https://github.com/masalib/create-react-app-gitpod/tree/db2a13e4d949918cd6e034f70086c9b0a22f93a5