近年、Webサービスやスマートフォンアプリの開発では、効率的なデータ通信を実現するためにさまざまなAPIが利用されています。
従来はREST APIが広く採用されてきましたが、近年ではより柔軟にデータを取得できる「GraphQL」が注目を集めています。
本記事では、GraphQLの基本的な仕組みからREST APIとの違い、メリット・デメリット、基本操作から実践的な操作方法まで、詳しく解説します。
GraphQLとは
次世代のWebAPI規格「GraphQL API」の概要
GraphQLは、Meta (旧Facebook) 社によって開発された、Web APIのためのクエリ言語および実行環境です。
必要なデータのみを1回のリクエストで取得できる仕組みとして公開され、特に複雑なデータ構造を持つSNSやECサイトなどで利用されており、多くの企業が導入しています。
REST APIでは、各リソースが固有のURLで識別されており、そのURLに対してリクエストを送信することでデータを取得します。
その際に、リソースに関するデータを全て取得するため、必要のない情報まで含まれてしまう場合があります。
また、取得したいデータの内容によっては、複数のURLにリクエストを送信する必要が出てきます。
GET /users/1
GET /users/1/posts
GET /posts/10/comments一方、GraphQLでは、以下のようなデータ構造を使用してリクエストを送るため、少ない回数で必要なデータのみを取得することができます。
query {
user(id: 1) {
name
posts {
title
comments {
text
}
}
}
}GraphQLはHTTP通信上で動作しますが、「どんなデータが欲しいか」をクライアント側が指定できる点がREST APIとの大きな違いです。
GraphQLの基本的な仕組みと構成
GraphQLでは、大きく2つの役割に分けてAPIを設計します。
- スキーマ(Schema) … どんなデータを取得・操作できるかを定義
- リゾルバ(Resolver) … 実際にデータを取得・操作する処理を実装
【スキーマ(Schema)】
APIで取得するデータの構造や操作方法などを定義する、いわゆるAPIの「設計図」です。
GraphQL schema Languageという独自の言語を使って、APIの仕様を定義します。
# 取得するデータの構造を定義
type User {
id: ID!
name: String!
age: Int
}
# データの取得方法を定義
type Query {
users: [User]!
user(id: ID!): User
}
# 追加や削除などの操作方法を定義
type Mutation {
addUser(name: String!, age: Int): User!
}リクエストする際は、上記のように定義されたスキーマに基づいてクエリを作成します。
【リゾルバ(Resolver)】
実際にデータを取得する処理を実装したものをリゾルバと呼びます。
JavaScriptやPythonなどの一般的なプログラミングで言う所の、クラスが保持するプロパティやメソッドを定義したものがスキーマなのに対し、メソッド内の実処理を定義したものがリゾルバです。
スキーマで QueryやMutationなどのデータ操作に関する型を定義した場合、同名の関数をリゾルバに実装する必要があります。
const resolvers = {
Query: {
users: () => users,
user: (_, { id }) => users.find((user) => user.id === id)
}
}GraphQLとREST APIの違い
エンドポイント(URL)の設計における違い
REST APIでは、エンドポイントごとにリソースの内容が固定されています。
そのため、取得内容が複雑化するほど、多くのエンドポイントにリクエストを送る必要が出てきます。
一方、GraphQLは REST APIとは異なり、単一のエンドポイントのみを利用します。
リソースごとにエンドポイントを使い分けるのではなく、リクエスト時に送るクエリの内容によって取得するデータを選別するのがGraphQLの特徴です。
データの取得方法における違い
上述したように、REST APIは取得するデータの内容によっては複数回の通信が必要 (アンダーフェッチ) になることがあります。
また、リソースごとに取得するデータ構造が固定されているため、必要のない情報まで含まれる (オーバーフェッチ) 可能性があります。
例えば、とあるエンドポイントにリクエストを送った場合のデータ構造が以下のように定められていた場合、nameだけが欲しいと思っていてもその情報だけを取得することはできず、定められている構造の通りにデータが返されます。
{
id
name
age
address
phone
}GraphQL の場合は、User型の中から nameのみ、Posts型の中から title とのみといったように、複数の型に分かれるデータも一度のリクエストでまとめて取得することができます。
query {
user(id: 1) {
name
posts {
title
}
}
}GraphQLのメリット・デメリット
GraphQLを採用するメリット
GraphQLを採用するメリットは、主に以下の内容が挙げられます。
- 必要なデータだけを取得できる … 通信量の制限に繋がる
- APIの呼び出し回数を減らせる … サーバーやネットワークの負荷を抑えられる
- フロントエンドとの相性がいい … 画面に必要なデータをそのままクエリとして記述できる
- 型安全性がある … スキーマによって各データの型が定義されているため、エラーが防ぎやすい
スキーマそのものがAPI仕様書となるため、構造を視覚的に理解しやすいのもメリットの1つです。
GraphQLを採用するデメリット
GraphQLはリクエスト時の柔軟性が高い反面、以下のデメリットもあります。
- 学習コストが高い … スキーマやリゾルバ、クエリの書き方など、覚えなければいけないことが多い
- セキュリティ面のリスクがある … クエリの柔軟性の高さを利用して、不正なクエリが実行される恐れがある
- キャッシュが複雑になりやすい … 単一エンドポイントへのリクエストとなるため、キャッシュが難しくなる場合がある
- レスポンスに時間がかかりやすい … 必要項目をまとめて取得するため、取得に時間がかかってしまう場合がある
また、複雑なデータ取得を必要としない小規模アプリケーションなどの場合、導入やAPIの設計にかかるコストが開発規模に見合わず、かえって効率が下がってしまう可能性があります。
GraphQLの3つの基本操作
データの取得を行う「Query」
REST APIのGETに相当するのが、Queryです。
以下のように、取得したいデータの内容を query {} で囲って記述します。
query {
books {
title
author
}
}{
"data": {
"books": [
{
"title": "GraphQL入門",
"author": "山田"
}
]
}
}データの作成・更新・削除を行う「Mutation」
REST APIのPOST、PUT、DELETEに相当するのが、Mutationです。
データ作成・更新・削除は全て Mutationで行います。
mutation {
createBook(
title: "AI入門"
author: "田中"
) {
id
title
}
}リアルタイム通信を可能にする「Subscription」
リアルタイムにデータを受信したい場合に使用するのが、Subscriptionです。
サーバー側でデータ変更などのイベント発生した際に、リアルタイムでデータを受け取ることができます。
subscription {
newMessage {
content
user
}
}例えば、チャットアプリや通知機能などの実装時に活用可能です。
GraphQL Playgroundを使ったクエリの実行手順
GraphQL Playgroundの概要と画面の見方
GraphQLをブラウザ上で実行できる GUIツールの1つに、GraphQL Playgroundがあります。
主な画面構成は、以下の通りとなっています。
・左:Query Editor
・右:実行結果
・▶:実行ボタン
・右側タブ:
Schema
Documentation
左ペインにクエリを記述し、実行ボタンを押してクエリを実行した結果が右側に表示されます。
実際にQueryを発行してデータを取得する方法
クエリの記述方法は、先ほども解説したように、取得したいデータ構造を query {} で囲って記述します。
query {
countries {
code
name
emoji
}
}{
"data": {
"countries": [
{
"code": "JP",
"name": "Japan",
"emoji": "🇯🇵"
}
]
}
}このように、クエリで指定したデータのみが返されます。
実際にMutationを発行してデータを更新する方法
Mutationも基本的な記述方法はクエリとほとんど変わりません。
追加や削除などのデータ操作に必要な情報を記述し、それらを mutation {} で囲います。
mutation {
addUser(
name: "Taro"
) {
id
name
}
}操作に成功すると、以下のように結果が返されます。
{
"data": {
"addUser": {
"id": 1,
"name": "Taro"
}
}
}まとめ
GraphQLは、柔軟なデータ操作を可能とする次世代のWeb API規格です。
通信量の削減やAPI呼び出し回数の削減が期待でき、特にSPAやモバイルアプリ、React・Next.jsを利用した開発との相性が良いとされています。
一方で、学習コストやサーバー負荷の管理など、導入時に考慮すべき点も存在します。
GraphQLの特徴を理解することで、より柔軟で効率的なWebアプリケーション開発を実現できるでしょう。