4. フロントエンドでGraphQLを使った所感(李 超)
最後は李の発表です。まだ日本語の情報も乏しい、策定したてのGraphQLと付き合っていく中で、苦労したポイントを紹介しました。
GraphQL
2015年11月頃、私たちは広告管理システムの移植をしました。中でも技術チャレンジとして、RESTの代わりにGraphQLを採用しました。GraphQLはFacebookが開発したクライアント・サーバ間のデータやりとりするためのクエリ言語で、2015年7月にRFCのドラフト案が公開されました。完全に新しい技術の故に、開発中に色々ハマりポイントがありました。今回はフロントエンドでのハマりポイントと改善案を紹介したいと思います。
言語及びフレームワーク
- フロントエンド:Javascript+AngularJS 1.5.X
- バックエンド:Scala+Slick+Sangria
ハマりポイント
クエリ変換時に罠が多い
GraphQLのクエリはJSONではないため、クライアント側で変換する必要があります。例えば、Stringのパラメータが求められる場合はこうなります。
const str = ‘abcde’; const query = `strParam: “${str}”`;
ただJavaScript側の変数をそのまま渡すとクエリエラーになりますので、変数の両側にダブルクオーテーションが必要です。
同じ感じで配列やオブジェクトも変換しなくてはなりません。
const arr = [ 1, 2, 3 ]; const query = `arrParam: [${arr}]`; const obj = { a: 1, b: 2 }; const query = `objParam: ${JSON.stringify(obj)}`;
その中でもenumが特殊です。こうなります。
const enum = { RED: ‘RED’, GREEN: ‘GREEN’ }; const `enumParams: ${enum.RED}`;
クエリが受け付けるのはキー名のみ、値で渡すとエラーになります。
.jsファイルが重い
クエリはすべてクライアント側が持っているため、初期ロード時間が長いです。クエリ数はおおよそ50くらいです。短いほうでも100文字以上、長いほうは3000文字近くあります。その上各画面用のクエリの取得カラムを最適化するためクエリのバリエーションも増え、似ているけど違うクエリがたくさんあり、それらがすべてminify不可の文字列としてクライアント側の.jsファイルに入りますので重いのも当たり前です。
コンソールでデバックしづらい
GraphQLは基本gqlへのPOSTとなるため、開発ツールのコンソールではすべてのリクエストが同じように見えます。
また、クエリ全体はPayloadのqueryかmutationになりますので、開発ツールのコンソールでは整形されないため非常に見づらいです。
サーバ側で処理の重さが把握しづらい
GraphQLが非常に柔軟性を持つ言語なので、スキーマさえ定義されていれば、クエリの組み合わせは自由にできます。それをクライアント側で決めると、サーバ側は何が来るか想定できなく、処理の重さも把握しづらいです。結局はフロントエンドで各処理の重さを理解した上でリクエストするという属人的なことになります。
改善案
クエリにvariablesを使い、クエリ自体をセグメント化
variablesはGraphQLがもっている機能の一つ、最初からクエリに使うパラメータの型を定義すれば、型を勝手に変換してくれます。記述が多くなりますが、変換がいらなくなるのでvariablesを使ったほうがいいです。
それぞれのクエリには共通な構造がありますので、その部分文字列をセグメントとして定数化し、流用することでメンテナンス性が上がり、.jsファイルのサイズも多少減ります。また、セグメントが増えすぎるとソースの見通しが悪くなりますので、セグメント化対象としてはバリエーションがない構造のみとしています。
Node.jsの中間サーバを用意、クエリをそちらに移動
セグメント化をしても.jsのファイルサイズがそこまで減らないため、中間のNode.jsサーバを作り、クエリをすべて中間サーバに移動しました。クライアントと中間サーバは従来のRESTに戻しました。RESTのAPIは基本一画面一つにし、後は中間サーバで適切なクエリを構築しリソースサーバにリクエストをします。また、場面によって中間サーバでは複数回のリクエストをし、そのレスポンスをまとめて整形してからクライアント側に返すようなこともできるようになります。中間サーバとリソースサーバの間はGraphQLのままなので、GraphQLの長所はそのままとなっています。
4.のまとめ
フロントエンドでGraphQLを色々やってみました。GraphQLは確かに柔軟性があり、学習コストも高くないですが、向き不向きがあると思います。ブログやタイムラインなどのクエリのバリエーションが少なく、mutationが簡単なサービスには使いやすいと思います。逆に、機能豊富、複数テーブル跨ぎな作成が多い管理画面には向いていないと思います。また、クライアント側で使うのもどうしても.jsファイルのサイズが大きくなりがちなのであまりおすすめできません。
GraphQLはまだまだ新しいので、使い方にも言語自体にも改善余地がたくさんあると思います。私たちのチャレンジで、GraphQLの導入を検討している皆様の参考になれば幸いです。
まとめ
以上、第1回「オレシカナイト」のレポートでした。
本イベントは、自分たちのしてきた「技術的挑戦」について一歩引いて考え、振り返りつつ次への礎とできる良い機会となり、参加者の方からもご好評をいただくことができました。是非、他社開発陣の方との共同開催も含めて、続けていきたい取り組みです。
オレシカナイト 第2回は「アドテク x golang」というテーマで6月23日(金)に開催します。