Hygraph(GraphCMS)で学ぶGraphQL 第1回 GraphQLとは
最近メジャーなサービスのAPIとしても採用されることが増えているGraphQLと、そんなGraphQLを使ったheadless CMSである、GraphCMSについて解説していきます。まずは概要を大きく捉えてみましょう。
GraphCMSからHygraphへサービス名の変更:GraphCMSは、2022年7月にHygraphに名称を変更しました。本記事のサービス名や画面キャプチャは記事公開時のものです。
はじめに
本シリーズでは、最近メジャーなサービスのAPIとしても採用されることが増えているGraphQLと、そんなGraphQLを使ったheadless CMSである、Hygraph(2022年7月にGraphCMSから名称変更)について解説していきます。
第1回目の今回は、GraphQL・GraphCMSの概要と特徴を、それぞれ紹介していきます。
サービス名称の変更
GraphCMSは、2022年7月にHygraphに名称を変更しましたが、本記事では、GrahpCMSを元に執筆されていますので、記事公開当時のサービス名や画面キャプチャになっています。
GraphQLとは
GraphQLとは、Web APIにおいて、そのインターフェースに利用されることを想定したクエリ言語と、そのクエリを実行するサーバーサイドのランタイムのことを指します。Facebookによって開発されたのち、オープンソース化され、現在はGraphQL Foundationによって管理されています。
GraphQLの採用事例
GraphQLは、開発元のFacebookをはじめとして、AirbnbやGitHubなど、海外の有名企業が採用しています。
一般的なWeb APIは、クエリストリングやリクエストボディに、キーバリューのペアやJSONなどを用いてリクエストを行います。GraphQLでは、これらのデータの代わりにGraphQLクエリをリクエストパラメータに渡すことで、リクエストを行います。
GraphQLの大きな特徴として、「クライアントが求めるデータを、データ構造を指定して問い合わせることができる」という点があります。それがどういうことなのか、次の節から解説していきます。
Web APIとGraphQLについて
Web API全般については、「Web API入門」を参照してください。このシリーズの最終回では、GraphQLの概要についても触れています。
データ構造を指定して問い合わせる
GraphQLの特徴について、実例を挙げて考えてみましょう。ここでは、CodeGridの著者紹介画面を、GraphQLを使って実装することを考えてみます。
この画面では、CodeGridの著者の情報が表示されています。著者の情報は、名前や肩書、アイコン画像と、執筆した記事一覧などで構成されています。
これらをまとめると、クライアントでの描画に使うデータは、次のような構造になっていると扱いやすそうです。実際のCodeGridの画面の「執筆した記事」データには、ほかにも、シリーズの情報やカテゴリ情報など含まれていますが、長くなってしまうのでここでは割愛します。
- 特定の著者
- 名前
- 所属
- 肩書
- アイコン画像(のURL)
- 説明
- 執筆した記事
- タイトル
- 第n回あるいは前編/後編
- シリーズタイトル
: (省略)
GraphQLの特徴は、このデータ構造をそのままクエリとしてリクエストすることができ、なおかつその構造のままデータが返ってくる、という点です。
上記のデータを取得するクエリは、次のようになります。
query { # データを取得するクエリですという宣言
author(where: {slug: "cancer"}) { # 特定の著者の…
name # 名前
affiliation # 所属
title # 肩書
icon { # アイコン画像の…
url # URL
}
description # 説明
articles(first: 1000) { # 執筆した記事(最大1000件)の…
title # タイトル
part # 第n回あるいは前編/後編
series { # 属するシリーズの…
title # タイトル
}
# 省略
}
}
}
ぱっと見ただけで、先ほどのデータ構造そのままになっていることがわかると思います。
このクエリを、GraphQLに対応したAPIにリクエストすると、次のようなデータが返ってきます。
{
"data": {
"author": {
"name": "宇野 陽太",
"affiliation": "PixelGrid Inc.",
"title": "フロントエンド・エンジニア",
"icon": {
"url": "https://media.graphcms.com/hK4SZ5OrQUuoQsA86Guh"
},
"description": "大手ソフトウェアダウンロード販売会社、ソーシャルアプリケーションプロバイダーなどで、デザイナー、マークアップ・エンジニア、フロントエンド・エンジニアとして、主にスマートフォン向けゲームの開発に携わる。2015年1月に株式会社ピクセルグリッドに入社。\nMVCフレームワークを用いたJavaScriptの実装や、メンテナブルなCSSの設計を得意とする。",
"articles": [
{
"title": "宇野 陽太編",
"part": "第8回",
"series": {
"title": "エンジニアに聞く、仕事の行方"
}
}
// 省略
]
}
}
}
トップレベルのキーが"data"
になっているなど、細かな点に違いはありますが、リクエストしたクエリと同じ構造のデータが返ってきました。
この特徴は、「クライアントが何を求めていて、サーバーが何を返してくるのか」ということを把握するのに、大きな助けとなります。それにより、データのやり取りのために割くリソースを減らし、UIの開発作業により注力することができるようになります。
最小のデータを最低限のリクエストで取得する
次に、CodeGridの著者の一覧画面を見てみましょう。
著者紹介画面と同じように、この画面で欲しいデータ構造を考えてみます。
紹介画面と同様に、名前や肩書、執筆した記事の一覧が必要そうです。著者の説明はここでは表示しないので、これは不要でしょう。同様に、記事の詳細も必要なさそうですが、記事数を計算して表示する必要があるので、このためにIDだけ取得することにします*。また、著者をクリックしたら、その著者の詳細画面へ遷移するようにしたいので、著者を一意に特定できる値も必要ですね。
*注:IDとは
GraphCMSではすべてのデータに固有のIDが自動で振られます。ID自体は必要ないのですが、記事数の計算のために何らかのデータを取得する必要があるため、ここではIDを指定しています。
このように考えてみると、一覧画面のデータは、以下のような構造になっているとよさそうです。
- すべての著者
- 名前
- 所属
- 肩書
- アイコン画像(のURL)
- 執筆した記事のID
- 一意に特定できる値
先ほどの詳細画面で取得したデータと比べて、こちらのほうが必要なデータの量が少ないことがわかると思います。
ということは、詳細画面のデータを使い回してしまうと、無駄なデータをクライアントに送ることになってしまいそうです。一覧用と詳細用で別々のAPI、ないしはデータを用意する必要がある、ということでしょうか?
そんなことはありません。そもそも、GrpahQLは単一のエンドポイントしか持たず、どのデータを取得するか、というのは、クエリによって決まります。REST APIのように、エンドポイントによって返すデータが決まるということはありません。
また、複数のデータ構造を用途に応じて用意しておく必要もありません。実際、CodeGridでは、一覧のデータと詳細のデータは、どちらも同じものを使っています。
前述したように、GraphQLでは、クライアントが求めるデータ構造をそのまま返すことができます。逆を言えば、クライアントが必要としない(リクエストしていない)データを返すことはありません。
上記のデータを取得する場合のクエリは、以下のようになります。
query { # データを取得するクエリですという宣言
authors { # すべての著者の…
name # 名前
affiliation # 所属
title # 肩書
icon { # アイコン画像の…
url # URL
}
articles(first: 1000) { # 執筆した記事(を、最大1000件)
id
}
slug # 一意に特定できる値
}
}
このクエリでリクエストをすると、次のようなデータが返ってきます。
{
"data": {
"authors": [
{
"name": "中村 享介",
"affiliation": "PixelGrid Inc.",
"title": "Jamstackエンジニア",
"icon": {
"url": "https://media.graphcms.com/08EPcNB2QwqcPWdriqBq"
},
"articles": [
{
"id": "cjyjugko1494j08304cbjki3z"
}
// 中略
],
"slug": "kyosuke"
}
// 中略
]
}
}
このように、クエリにの構造を変更すれば、サーバーはその通りのデータを返します。
GraphQLでは、サーバー側では単一のデータ構造を再利用しつつ、クライアントに返すデータのサイズは削減する、といったことが可能になります*。
*注:REST APIでレスポンスを間引く
GraphQLの特徴として、クライアントが必要なデータのみレスポンスすることができる、という点を挙げましたが、この動作自体は、GraphQLでしかできないものではありません。
REST APIの場合でも、パラメータとして、レスポンスするフィールドを指定することができるようになっているAPIに出会ったこともあります。ただ、GraphQLと比べると扱いづらく、手間が多いというのが、筆者の感想です。
また、詳細画面でもそうでしたが、著者データと一緒に、執筆した記事のデータも返ってきています。これを見ると、著者のデータと記事のデータは分けるべきでは……と思う人もいるかもしれません。
CodeGridでは、著者のデータと記事のデータを、1つのデータとして扱っているのか? というと、それも違います。著者のデータと記事のデータは、サーバー上ではまったく別のデータとして登録されています。著者のデータの一部として記事のデータへの参照を持っているにすぎません。
このようなデータ構造を、きちんと設計されたREST APIで取得しようとすると、まずはじめに著者APIから著者のデータを取得した後、その中に含まれる記事IDを使って、記事APIにリクエストする……というように、複数のAPIにリクエストをしなければなりません。REST APIでは、データの種類ごとにエンドポイントを持つように設計します。
GraphQLでは、前述した1つのエンドポイントに対して、1つのクエリでリクエストしたデータは、参照さえ張られていれば、どれだけデータ構造が分かれていても、1回のレスポンスで返ってきます。このように、最小のデータを最低限のリクエストで取得可能であるという点も、GraphQLの特徴です。
ここまで述べた、GraphQLの特徴をまとめると、次のようになります。
- クライアントが求めるデータを、データ構造を指定して問い合わせることができる
- 最小のデータを最低限のリクエストで取得可能である
Hygraph(旧GraphCMS)とは
このシリーズのもうひとつのテーマである、Hygraph(旧GraphCMS)は、GraphQLの周辺ツールのうちの1つです。GraphCMSは、ドイツのGraphCMS社が開発・提供するheadless CMSです。データの取得や更新を行うためのAPIに、GraphQLを採用しています。CodeGridでもGraphCMSを採用しており、次のような画面になります。
GraphCMSはGraphQLを採用しているため、描画に必要なデータを柔軟かつ効率的に取得できるのが、大きな特徴です。CodeGridでも、リニューアルに際して、記事や著者などのデータをGraphCMSへと移行しました。メディアサイトくらいの規模であれば、相互に参照する必要のあるデータも多く、GraphQLの恩恵を得られる場面は多いのではと感じています。
GraphQL以外にも、データ型に合わせて選べるGUIや、Publish/Draftなどのステージの概念なども提供されており、実案件でのCMSとしても十分な機能を持っています。
とはいえ、GraphCMS以外のheadless CMSはGraphQLを扱えないかというと、そういうわけではありません。GraphCMSとの比較対象として挙がることが多いcontentfulもGraphQLを扱えますし、機能的にも大きな差はありません。
ただ、公式サイトのトップページにも「GraphQL native Headless CMS」とあるように、GraphCMSはGraphQLを中心に作られたheadless CMSです。ですので、ここではGraphQLを扱う際のheadless CMSの候補としてGraphCMSを取り上げていきます。
また、CodeGridでheadless CMSを選定した時点では、contentfulでは有料の上位プランでないとGraphQLが使えなかったため、GraphCMSを選んだという経緯もあります。現在はcontentfulでも無料プランで利用できます。
GraphCMSに関しては、次回以降、詳しく解説していきます。
GraphQLのそのほかの周辺ツール
GraphQL以外にも、GraphQLはその開発をサポートするツールやライブラリが充実しています。
たとえば、GraphQLを使ったリクエストを、Reactコンポーネントから実行しやすくするものとして、Apollo ClientやRelayなどがあります。Apollo Clientには、React向けのライブラリのほか、AngularやVue向けのライブラリも公開されています。
graphql-tagやeslint-plugin-graphqlなど、クエリを静的解析にかけ、構文のチェックをしてくれるものもあります。これらを使えば、実際にリクエストを行わずとも、構文レベルでの間違いなどに気づくことができます。
クライアントから送られたクエリを受け取って実行する、GraphQLサーバーには、本家GraphQLプロジェクトが開発しているGraphQL.jsや、そのほかにApollo Serverなども有名です。また、JavaScript(Node.js)以外にも、数多くの言語の実行環境が作られています。
周辺ツールの中で規模の大きいものとしては、GraphiQLが挙げられます。これは、ブラウザ上でGraphQLクエリの実行環境を動かすというものです。GraphQLサーバーとあわせて、GraohiQLをホスティングしておけば、プログラムを一切書かずにクエリを実行することができます。
まとめ
今回は、GraphQLの特徴と、GraphCMSの概要について取り上げました。
GraphQLを使用することで、データを柔軟に取得することができるようになり、開発リソースをUIの開発に集中させることができます。また、効率的にデータを取得するので、パフォーマンス面でも優れています。ここではCodeGridを例に取り上げて解説しましたが、このようにUIを構築するためのデータが多岐にわたる場合、GraphQLは開発を強力に支援してくれます。
その一方で、データの種類もデータ量も少ないような場面では、これらの恩恵が得られず、オーバーヘッドのほうが目立ってしまう場合もあります。次回以降、どのようなデータをどのように扱っていくかを、具体的な例を通して解説します。
次回はGraphCMSについて解説していきます。