SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

イベントレポート

サイバーエージェントのエンジニアがハマった・失敗したポイントを語る「オレシカナイト Vol.1」イベントレポート


  • X ポスト
  • このエントリーをはてなブックマークに追加

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日(金)に開催します。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
イベントレポート連載記事一覧

もっと読む

この記事の著者

平松 紘典(株式会社サイバーエージェント)(ヒラマツ コウスケ)

 サイバーエージェント メディア広告部門(MDH) チーフアーキテクト 2011年サイバーエージェントに中途入社。スマートフォンPigg、Amebaスマートフォンプラットフォーム、ブログ等を担当。 現在は広告配信システムの開発チームにて、プログラマ/アーキテクト/クラウドインフラなどを担当している。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

海老澤 直樹(株式会社サイバーエージェント)(エビサワ ナオキ)

 株式会社AbemaTV/サイバーエージェント メディア広告部門(MDH) 兼務 2011年サイバーエージェントに中途入社。オフィシャルブログ、アメスタ、GAMYで主にJavaを使ってサーバーサイドを担当。現在はAbemaで広告入稿の支援ツールをScalaやGoで作ったり、AWSのインフラを担当して...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

小坂 和弘(株式会社サイバーエージェント)(コサカ カズヒロ)

 2009年サイバーエージェントへ入社。Pigg、ゲーム部門でのバックエンド、フロントサイド開発を担当。2015年よりメディア広告部門(MDH)にて広告運用管理画面の機能実装と関連サーバアプリケーションの開発を主に担当している。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

李 超(株式会社サイバーエージェント)(リ チョウ)

 サイバーエージェント メディア広告部門(MDH) 2015年サイバーエージェントへ中途入社。メディア広告部門(MDH)にて、フルスタックを目指しながらフロントエンジニアとして従事。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10218 2017/06/20 18:21

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング