フロントエンド開発をしていると、API 連携はほぼ必ず登場します。
その中でよく比較されるのが REST API と GraphQL です。
名前は知っていても、実務でどう違うのか、フロントエンドの実装にどう影響するのかは意外と曖昧になりやすいと感じます。
この記事では、フロントエンド開発者の視点で両者の違いを整理します。
この記事で整理すること
- REST API と GraphQL の基本的な違い
- フロントエンド実装で何が変わるのか
- それぞれの得意な場面
REST API の基本
REST API は、リソースごとにエンドポイントが分かれている設計です。
操作の種類は HTTP メソッドで表現し、CRUD と以下のように対応します。
| 操作 | HTTP メソッド | エンドポイント例 |
|---|---|---|
| 一覧取得 | GET |
/users |
| 詳細取得 | GET |
/users/:id |
| 新規作成 | POST |
/users |
| 更新 |
PUT / PATCH
|
/users/:id |
| 削除 | DELETE |
/users/:id |
フロントエンドは、必要な操作に応じて対応するメソッドとエンドポイントを呼び出します。
たとえば「ユーザー情報を取得したい」ときは以下のようになります。
GET /users/1
{
"id": 1,
"name": "Taro",
"email": "taro@example.com",
"age": 28
}
「新しいユーザーを作成したい」ときは以下のようになります。
await fetch("/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Hanako", email: "hanako@example.com" })
});
URL を見れば「どのリソースに対して何をしているか」が分かりやすく、直感的に理解しやすい設計です。
バックエンドとの会話でも「この画面はこの API を使う」と整理しやすく、多くの現場で扱いやすいのが特徴です。
GraphQL の基本
GraphQL は、クライアントが欲しいデータの形を指定して取得する仕組みです。
REST のようにエンドポイントが複数に分かれるのではなく、基本的には 1 つのエンドポイントに対してクエリを送ります。
たとえば「ユーザーの id と name だけ欲しい」場合は、以下のように書きます。
query {
user(id: 1) {
id
name
}
}
{
"data": {
"user": {
"id": 1,
"name": "Taro"
}
}
}
必要な項目だけを明示的に指定できるのが大きな特徴です。
データの更新や作成には mutation を使います。
たとえば「新しいユーザーを作成したい」場合は以下のように書きます。
mutation {
createUser(input: { name: "Hanako", email: "hanako@example.com" }) {
id
name
}
}
REST では HTTP メソッド(GET / POST / PUT / DELETE)で操作を区別しますが、GraphQL では query(取得)と mutation(変更)という形で区別します。
この記事では主にデータ取得の違いを中心に見ますが、更新処理にもそれぞれの考え方の違いが出ます。
フロントエンド実装で何が変わるのか
フロントエンド目線で見ると、一番大きな違いは データ取得の組み立て方 です。
| 観点 | REST API | GraphQL |
|---|---|---|
| データの形を決めるのは | サーバー側 | クライアント側 |
| 取得の感覚 | 用意された API を使う | 必要なデータを問い合わせる |
| エンドポイント | リソースごとに複数 | 基本的に 1 つ |
この違いが、画面実装の進め方に影響します。
データ取得の違い
REST API では、画面に必要な情報を揃えるために複数の API を呼ぶ場面があります。
たとえば、プロフィール画面でユーザー情報・投稿一覧・フォロワー数が必要だとすると、こうなることがあります。
const user = await fetch("/users/1");
const posts = await fetch("/users/1/posts");
const followers = await fetch("/users/1/followers");
このように、画面が複雑になるほど API の呼び分けやレスポンス整形の責務がフロント側に寄りやすくなります。
一方 GraphQL では、関連するデータを 1 つのクエリにまとめて取得しやすいです。
query {
user(id: 1) {
id
name
posts {
id
title
}
followers {
count
}
}
}
そのため、画面によっては通信回数やレスポンス整形の手間を減らしやすくなります。
ただし、実際の効率はバックエンドのスキーマ設計や実装にも左右されます。
また、REST でもバックエンド側で画面向け API が用意されていれば、同じように取得回数を減らせることがあります。
更新処理の違い
REST API では、HTTP メソッドを使い分けて更新系の操作を表現します。
// 投稿を新規作成
await fetch("/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "新しい記事", content: "..." })
});
// 投稿を更新
await fetch("/posts/1", {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "更新後のタイトル", content: "..." })
});
// 投稿を削除
await fetch("/posts/1", { method: "DELETE" });
GraphQL では mutation を使って変更を表現します。
mutation {
updatePost(id: 1, input: { title: "更新後のタイトル", content: "..." }) {
id
title
}
}
REST は HTTP の考え方に沿っていて直感的に理解しやすく、GraphQL は取得と同じ考え方で更新処理も扱える、という違いがあります。
それぞれの得意な場面
REST API が向いている場面
- シンプルで学習コストを抑えたい
- API 単位で責務を分けて設計したい
- Network タブで通信内容を追いやすくしたい
REST API は、エンドポイント単位で役割が見えやすく、初めて API 連携に触れる場面でも理解しやすいです。
GraphQL が向いている場面
- 1 画面で複数種類のデータを扱う
- 必要なデータだけを柔軟に取得したい
- フロント主導で取得項目を組み立てたい
- TypeScript と型生成を活かして開発したい
GraphQL は、画面ごとに必要なデータが変わりやすいアプリケーションや、関連データをまとめて扱いたい場面で強みが出やすいです。
一方で、クエリ・ミューテーション・スキーマといった概念に慣れる必要があり、導入や運用の難易度は REST より上がることがあります。
まとめ
- REST API は、リソースごとのエンドポイントと HTTP メソッドで操作を表現する
- GraphQL は、必要なデータをクライアント側で指定して取得する
- REST はシンプルで理解しやすく、既存システムや一般的な現場で扱いやすい
- GraphQL は複雑な画面や型安全な開発と相性がよい
- どちらが優れているかではなく、画面要件やチーム構成に合うかで考えることが大切