これは新歓ブログリレー2026 19日目(?)の記事です。
ちなみに画像は、GraphQLから連想しようとして思いつかなかったので、今日の夕飯が酢豚だったことから昔食べた酢豚定食です。
はじめに
この記事では、GraphQLって何って話と、公開されているGraphQLのAPI(後述)を使ってふざけたことをしようという記事です。
GraphQLって何よ
その前にAPIとは
GraphQLの話をする前にAPIについての説明をします。APIは Application Programming Interface の略で、ソフトウェア間のインターフェースであり、異なるアプリケーション間で通信して機能や情報を共有するための規格のことです。APIによって、ある提供者(サーバー)の情報や機能を利用するために、利用者(クライアント)がどこ(エンドポイント)に対して、どのような情報とともに、どのような形式で質問(リクエスト)すれば、どのような形式で情報が返されるか(レスポンス)が決められています。そのため、APIを把握して従ってさえいれば情報や機能を使えるという利点があります。
そして、APIにもいくつか種類があります。先ほど話した「情報・機能を共有するための形式」に対する形式にもいくつかあるということです。その中の一つがGraphQLです。
GraphQLとは
GraphQLはMeta(FaceBook)が開発した、クライアントがレスポンスのデータの形式をサーバーに対して指定できるクエリ言語です。サーバーにある一つのエンドポイントに対し、クエリというレスポンスのデータ型を指定するものを送ることで、定義された範囲内で好きな型のデータが得られます。これがGraphQLの大きな特徴の1つです。
APIの種類の中でもっとも一般的ものとしてRestAPIというものがありますが、これは一つのエンドポイントに対してリクエストの型が1つに決まっているため、様々な型のレスポンスに対応するにはたくさんのエンドポイントをサーバー側が準備する必要があります。GraphQLでは代わりに、クエリで指定できる範囲をしっかりと定義する必要があります。これをしっかりやるかどうかでクライアントが指定できるレスポンスの型の自由度が決まります。
メリット・デメリット
これらの特徴から、様々なメリット・デメリットがあります。
まずメリットとして、RestAPIでは様々なエンドポイントから情報を集めてまとめる作業がいるような場面でもGraphQLでは一つのエンドポイントから一回でまとまった情報が得られます。エンドポイントから情報を得る、という操作はネットワークの通信が起きるため回数を重ねるほど通信が遅くなります。そのため一度で情報が得られるとその分早くなります。また、RestAPIではあるエンドポイントから集めたデータのうち一部が不要なデータである場合がありますが、GraphQLではこのようなことは起きません。
ただ、デメリットとしてRestAPIに比べてGraphQLはあまり普及してないうえ学習コストが重いです。GraphQLができたのは2015年と最近の技術であるため知ってる人も少ないですし、それにより参考にできる情報も少ないです。
いったんまとめ
色々書いてきましたが、ざっくりGraphQLは以下のようなものです。
- APIの一つ
- クライアント側でレスポンスの型を指定できる
- メリット
- 一度のリクエストで必要なデータを集められる
- デメリット
- 学習コストが重い
これらの話を見て興味がわいた人はぜひ触ってみてください。
触るぞ、遊ぶぞ
ここまででGraphQLについて知った中で、「結局どんな感じに触るの?」と思う人もいるかもしれません。ただ、こう思ったときに「じゃ試しに自分で作って触ってみよう」とはいきません。上で述べたように学習コストが重いので、大体の人は完成する前に挫折するか無駄に時間かかるかです。
そんなあなたに朗報(?)。この世にはいくつかGraphQLのAPIが全世界に公開されています。
例として、Countries GraphQL API(Github,Playground)やSWAPI-GraphQL(playground)があります。前者は国名やその首都名、公用語などの情報を得られるAPIで、後者はスターウォーズ関連の情報が得られるAPIです。(なんでスターウォーズなのかは知りません。)これらのplaygroundにアクセスすると、クエリを書きそのクエリに対するリクエストがどうなるかを試せます。ウェブページとして整っているので比較的触りやすいかなと思います。
今回はわかりやすいようCountries GraphQL APIで一つ遊んでみます。(私がスターウォーズをあまり知らないというのもあります。)まず手始めにすべての大陸の名前を取得してみましょう。
query {
continents{
name
}
}
このように入力して実行ボタン(緑背景の三角ボタン)を押すと以下のように返ってきます。
{
"data": {
"continents": [
{
"name": "Africa"
},
{
"name": "Antarctica"
},
...(省略)...
]
}
}
queryにcontinentsのnameを指定すると大陸名を全取得できていますね。
続いて、クエリを以下のように書き換えます。
query {
continents{
name
countries{
name
}
}
}
すると今度は、大陸名に加えてその大陸にある国名を取得できます。ではまたクエリ以下のように書き換えてみましょう
query {
continents{
name
countries{
name
continent{
name
}
}
}
}
これは、すべての大陸にあるすべての国名に対して、その国がある大陸名を返します。はい。ある大陸上にある国名に対してその国がある大陸を返すとかいう無意味なことをさせるクエリですね。
これで分かるように、GraphQLの仕様上continentやcountoryに対してどのような情報を返すことができるのかという部分は定義されていますが、循環させることは禁止事項ではありません。
ということで...
query {
languages{
countries{
languages{
countries{
name
}
}
}
}
}
「各言語に対し公用語にしてる国を返し、その国の公用語を返し、その言語を公用語にしている国名のリスト」を返すクエリです。内容から察せるように、レスポンスは膨大でその行数はなんと64186行。相当余計な行はありますが、なげー。それでも1秒かからずレスポンスが来てますね。流石機械。
じゃあもっと増やしてみましょう。これで、どうだぁ!
query {
languages{
countries{
languages{
countries{
languages{
countries{
name
}
}
}
}
}
}
}
{
"type": "https://developers.cloudflare.com/support/troubleshooting/http-status-codes/cloudflare-1xxx-errors/error-1102/",
"title": "Error 1102: Worker exceeded resource limits",
"status": 503,
"detail": "A Worker script configured by the website owner exceeded its resource limits (CPU time or memory) and was terminated.",
...(省略)...
}
.....そりゃそう。レスポンスを返すまでの時間が長すぎて怒られました。サーバー側もこんなこと想定してないはずがありません。こんな風にサーバー側でCPUやメモリ等のリソースで制限する方法もありますし、クエリに対して複雑度というものを定義しておき、一定値以下のものしか対応しないといった対策もあります。この辺りは実際に実装して触れてみてください。
おわりに
いかがでしたか。後半は遊び8割くらいでしたがGraphQLを知って興味が出てきたでしょうか。GraphQLのplaygroundに関しては、左にあるアイコンからどんなクエリが書けるのかの仕様が書かれているのでもっと触りたい人は参考にしてみてください。
では。
次回は@genmiraさんの記事です。お楽しみに。