WebエンジニアのLoL日記

LoLをプレイしたりLJLの試合を見たりするのが好きなエンジニア。LoLのイベントやパッチノートなど気になった点を記事にしたり、LJLについの記事をかいたりしています。某社でWeb系のエンジニアとして働いているので、技術系の記事もたまに書きます。コンタクトを取りたい場合はtwitterまで。

GraphQLが注目を集め始めた理由と、Reactとの相性を考える

f:id:yoshiki_utakata:20181203174451p:plain

この記事は?

なぜGraphQLが最近注目を集め始めたのかと、GraphQLとReactとの相性について自分なりの見解を書きます。

概要

なぜGraphQLが最近注目を集め始めたのかというと、React、Vueなどが登場し、フロントエンドの実装がコンポーネント指向になってきたからです。

  1. コンポーネント指向とはなにか
  2. なぜコンポーネント指向になるとGraphQLがいいのか

大まかにこの順序で説明していきたいと思います。

コンポーネント指向とはなにか

例えばtwitterの一つのツイートを考えます。

f:id:yoshiki_utakata:20190128224713p:plain

例えばこれを表示するための Tweet コンポーネントがあったとします。中身はこんな感じです。

<img src="{{iconUrl}}" onClick="{{profileUrl}}">
<div>{{displayName}}</div>
<div>{{screenName}}</div>
<div>{{tweetBody}}</div>
...

細かいところは省略します。

で、このコンポーネントを使って、次にツイートを並べたページがあります。

f:id:yoshiki_utakata:20190128225046p:plain

これはこのようにできます。

<Tweet iconUrl="..." onClick="..." displayName="..." ...>
<Tweet iconUrl="..." onClick="..." displayName="..." ...>
...

さて、このようにコンポーネントにしておくと便利なのは、色んな所でこのコンポーネントが使い回せる点です。例えば

  • ホームタイムライン
  • お気に入りページ
  • 自分のユーザーページにあるタイムライン

それぞれのページで微妙に表示している要素は異なりますが(例えば、自分のプロフィールが書いてあったり、ツイートを書くテキストボックスがあったり)、ツイートの表示自体はすべて同じです。このような場合に一つツイートのコンポーネントを作っておけばどこでも使い回せるのがメリットとなります。

なぜGraphQLとコンポーネント指向の相性がいいのか

フロントエンドのコンポーネント指向の先駆けであるReactはFacebookが開発したものです。GraphQLもFacebookが開発したものです。両者ともにFacebookが開発したものがあるゆえ、なんとなく相性はいいんだろうなと思っていましたが、なぜ相性がいいのかはいまいちわかっていませんでした。

コンポーネント指向において、重要なのは コンポーネントを作成するのに必要な要素が何であるか ということです。例えば、ツイートのコンポーネントを表示するのに必要なものは

などとなってきます。

従来のREST APIの場合、「コンポーネントにこれが必要だからAPIでこれを返すようにしよう」となります。フロントエンドとサーバーサイドの合意が必要になります。その結果、フロントエンドのコンポーネントで行ったモデリング(ツイートを表示するために何の要素が必要であるか)と同じことをサーバーサイドで行う必要が出てきます。

class User {
  string screenName;
  string displayName;
  ...
}

class Tweet {
  User user;
  string body;
  ...
}

ここで、クライアントに必要な情報を不足なく定義する必要がありますし、クライアントが必要な要素が変わるとサーバーサイドに手を入れなければいけなくなります。

しかしGraphQLですと、クライアントが必要な要素を列挙します。クライアントサイドはその気になれば何でも返せるように実装しておきますので、同じモデリングを2回する必要がなくなります。「クライアントが表示に必要なものについて」の定義がすべてクライアントサイドにまとまっているのです。

クライアントとサーバーサイドの分離

もう一つ上げるとすれば、クライアントサイドとサーバーサイドの分離です。ReactやVueなどのVirtual DOMの誕生により、今までWebフレームワークが担っていた「テンプレートの描画」が、クライアントサイドに移譲されることになりました。その結果、必要な通信はすべてAPI経由になったりと、サーバーサイドとクライアントサイドの分離が進んできました。

REST APIAPIの仕様をクライアントサイドが把握していなければならず、逆に、クライアントがほしい要素をサーバーサイドは返してあげなければならないので、両者はまだ密接にくっついているといえます。

しかしGraphQLはクライアントサイドが必要な要素を要求、サーバーサイドは要求されたものを返すだけなので、REST APIよりももう一段階「サーバーサイドとクライアントサイドの分離」が進んだ形となります。

スマートフォンタブレットなどの多様なデバイスの登場

ここだけはReact関係ないのですが、多様なデバイスが登場し「スマートフォンだけ微妙に表示を変えたい」「タブレットだけこれを表示したい」といったような微妙な変化を持たせられるもの一つあるのかなと思います。

まとめ

実際にRest APIとVueなどを利用して開発してみると、「Vueでこの要素を表示するためにはこれとこれとこれが必要なので、このAPIではこれとこれとこれを返すようにしなければいけないな」と、サーバーサイドとクライアントサイドのモデリングの一貫性を考慮する場面に多く直面しますが、GraphQLにすることでモデリングの手間をへらすことができます。一方で当然GraphQLにはGraphQLのデメリットもあります。*1 が、Reactとの相性悪くなさそうだなぁと感じた次第でございました。そして現代の要求にはGraphQLは非常に合致しているかと思います。

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

*1:この記事はGraphQLのメリット/デメリットを検討する記事ではないので詳しくは省略します。