5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GraphQLクライアント周り調べて設定した

Posted at

雑多な感じです

TypeScript編

サンプルリポジトリ: https://github.com/sisisin-sandbox/try-gql/pull/1
(業務で使ってる構成の再現構成となっています)

クライアントライブラリ選び

多分選択肢はこんな

観測範囲でapollo使ってるのを多く見ていた/relayはReact特化っぽい/apolloのclient cacheを使うケースがありそうなどでapollo clientを選択
(といいつつrelayはろくに調べてないです)

apollo client設定

apollo clientについて

doc: https://www.apollographql.com/docs/

apolloはreact向けのクライアント以外にもサーバー実装・iOSクライアント・graphqlの運用サポートSaaSという具合に色々提供してくれてるすごいやつ(小並感)
この記事ではreact向けクライアントについて書きます

apollo clientはサーバーへのqueryはもちろんgraphql schemaを用いたローカルの状態管理の仕組み、middleware的なレイヤー(apollo-link)など様々な機能があります
この辺多少調べて設定したのでそれについて書いていきます

やったこと

  • ApolloClientをapollo-boostを使わずに設定(apollo-boostは設定を細かく出来ないので
  • apollo client:codegenコマンドによる型定義コード生成
  • vscodeのapollo clientプラグイン設定

ApolloClientをapollo-boostを使わずに設定

ドキュメントにapollo-boost/apollo-clientの例が入り混じってて大変紛らわしいやつ
apollo-boostはエントリー用パッケージのようなので実戦投入するなら自前でapollo-clientを設定するのが良い
(apollo-client v3ではapollo-boostぐらいのお手軽設定から始められるようになるっぽい)

初期設定自体はapollo-boostからのマイグレーションというドキュメントがあるのでこれを見ればいい
参考リンク: https://www.apollographql.com/docs/react/migrating/boost-migration/

apollo client:codegenコマンドによる型定義コード生成

typescript使うなら型定義の生成は人権
選択肢としては他にもいくつかあったが、apollo-clientを利用することにした

他の選択肢

選んだ理由としては、

  • 一通りの機能をサポートしている
    • 例えばts-graphql-pluginは別名に対応してないなどがある
  • 同じエコシステムにしとくほうが無難な気がした(完全に個人の感想)
    • apollo client v3でcustom scalarのdeserializeが書けるようになりそうで、もしそこと生成する型定義が上手くつなぎ込めるなら・・・?という希望もあった
  • graphql-code-generator乗り換えは検討しても良いかも?とは思っている
    • 機能はこちらのほうが豊富(後述)

その他細々と以下のような設定をしたりしました

  • globalTypes.ts/__generated__ ではなく /src 配下へ配置
    • create-react-appなどを利用する場合に取り回しやすいように
  • コード生成時に --customScalarsPrefix を付け、 global.d.ts のようなファイルを配置してそのファイル内で declare type GitHubDate=string のように定義
    • まあサンプル通りですが
  • introspectionを使わずschema.graphqlをダウンロードしてきてコード生成に利用
    • 諸般の事情によりサーバーがVPN内にいてCIからエンドポイントを叩けないのでこのような構成に

vscodeのapollo clientプラグイン設定

インストールするだけっちゃするだけ
fragmentとかへ定義ジャンプ出来たりフィールド名のサジェストが出てきたりして便利
これがないとschemaを手書きすることになるので大変です

やってない(やれてない)こと

  • apollo-link-scalarsを用いたデータ取得時のcustom scalarのdeserialize
  • vscodeのgraphql プラグインによるエディタからのquery実行
  • graphql code generatorによるコード生成
  • ApolloClientのラッパー実装

apollo-link-scalarsを用いたデータ取得時のcustom scalarのdeserialize

custom scalarとして定義された Date 型(ISO 8601形式文字列であるとする)をfetchしてきて受け取った時点で new Date(val)しておきたい、というのが人情だと思うんですよ(?)
サーバーサイドでは実際そういう仕組はあるけれど、apollo clientではcustom scalarに対してそういった統一的なfetch時のdeserialize処理を挟むことが出来ません

そこでapollo-linkの仕組みを利用して、fetch時にcustom scalarをdeserializeする処理を挟み込んでやってしまおう、というのが apollo-link-scalars というライブラリのアイデアです
が、問題点があり、

  • apollo-cache-persist などのhttpを経由しない値の取得で意図通り動かない
  • apollo-link-scalars の実装ではサーバーサイド向けの実装に依存している( Example of loading a schema参照のこと)
    • 結果、bundleサイズがやべえことになる
      • 仮にそこを無視できるとしても、 サーバーサイド実装はユニバーサルなjsとしてメンテされる保証がないのでリスキー
      • 現時点で graphql-tools はfsに依存してたりしてcreate-react-appなどではそのままでは動かない
    • ついでにschema.graphql相当の文字列を突っ込むだけでも結構サイズが膨れる

custom scalar対応のfeature requestはあるのでapollo client v3に期待・・・?

vscodeのgraphql プラグインによるエディタからのquery実行

ちょっと触って詰まったのでちゃんと調べてない・・・(後で試したい)

graphql code generatorによるコード生成

先述したようにapollo client:codegenを利用してるのでこちらはやってません
機能的にはこちらのほうが出来ることは多いので再検討しても良いかもとは考えてます

  • cameCaseの別名で一括解決してくれる
  • custom scalar向けの型を独自定義できる
  • 生成した型を利用するreact hookも一緒にコード生成してくれる

ただコード生成って機能が豊富になっても初手の手数が減るだけなのでよっぽど魅力的じゃないとわざわざ乗り換えるほどでもない、とはなりそう・・・

ApolloClientのラッパー実装

例えばreduxのmiddlewareレイヤーでクライアントを使いたい場合に欲しいはずなのでそのうちやるつもりです
具体的には、graphql errorのときにrejectedなPromiseが返ってくるためにanyで推論されてしまって、せっかく GraphQLError 型があるのに使いにくい、というような点が挙げられます
他には queryメソッドの型引数が省略可能(デフォルトany)になるなど、微妙な点があるのでその辺をラップした自前のクライアントクラスを作ろうかなとは考えてます
この辺は追々。

Scala編

sbt-graphqlの話を書こうと思ったけどタイムアップ

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?