---
title: "GraphQLとは？読み方・REST APIとの違いとクエリ・リゾルバの書き方をわかりやすく解説"
url: "https://www.issoh.co.jp/tech/details/2924/"
published: 2024-07-04
updated: 2026-10-27
categories: ["GraphQL"]
publisher: "株式会社一創"
---

# GraphQLとは？読み方・REST APIとの違いとクエリ・リゾルバの書き方をわかりやすく解説

GraphQL（グラフキューエル）とは、クライアントが「どの形のデータが欲しいか」をクエリで書き、サーバーがその形どおりにJSONを返すAPIのクエリ言語です。Facebook（現Meta）が2012年から社内で使い、2015年に仕様を公開しました。この記事では、REST APIとの違いを押さえたうえで、引数・エイリアス・`@include`を使ったクエリの条件指定、リゾルバの仕組みとN+1問題、Node.jsで動かす最小構成までを、手元で実行した結果つきで説明します。版番号と制限値は2026年10月27日時点で公式情報を確認した値です。

## まとめ：GraphQLは欲しいデータの形をクライアントが書くAPIのクエリ言語

GraphQLのAPIは原則1つのエンドポイントで、クライアントがフィールドを選んで問い合わせます。RESTで起きやすい「使わない項目まで返る（オーバーフェッチ）」「足りずに何度も呼ぶ（アンダーフェッチ）」を減らせるのが一番の利点です。

- 要素はスキーマ（型の定義）、クエリ（取得）、ミューテーション（更新）、リゾルバ（値を返す関数）の4つ
- 条件は引数で指定し、変数・エイリアス・`@include`／`@skip`で出し分ける
- 代償はHTTPキャッシュの効きにくさ、N+1問題、重いクエリによる負荷。DataLoaderと深さ制限で抑える
- Postmanの2025年調査ではAPI開発者の33%がGraphQLを利用（RESTは93%）。置き換えではなく併用が主流

Webとモバイルなど複数の画面からデータを組み合わせて取るシステムなら採用、単純なCRUDやCDNキャッシュ頼みの公開APIならRESTで十分です。以下、仕組みから順に見ていきます。

## GraphQLの意味と読み方、Facebook発の成り立ち

読み方は「グラフキューエル」で、Graph Query Languageの略です。データを型どうしのつながり（グラフ）として捉え、クエリでたどって必要な部分だけを取り出す、という発想から名付けられました。グラフデータベース専用の言語ではありません。

### 1つのエンドポイントで必要なフィールドだけを返す仕組み

RESTでは`/users/1`と`/users/1/posts`のようにリソース別のURLを使う設計が一般的ですが、返す項目や関連データを引数で選べるAPIもあります。GraphQLは通常`/graphql`の1か所に問い合わせ、返してほしいフィールドをクライアントが列挙します（[公式ガイド Serving over HTTP](https://graphql.org/learn/serving-over-http/)）。画面に名前と投稿タイトルしか出さないなら、その2つだけを書けば応答もその2つだけになり、クエリはスキーマ（型の定義）で検証されてから実行されます。

### 2012年のFacebook社内利用からGraphQL Foundation設立までの経緯

公式サイトによると、Facebookのモバイルアプリは2012年からGraphQLで動いており、仕様は2015年にオープンソース化されました（[graphql.org](https://graphql.org/)）。画面ごとに必要なデータが違うモバイルで、RESTの往復回数と転送量が問題になったことが開発の動機です。2018年11月6日にはLinux FoundationがGraphQLを支える財団の設立を発表し（[発表記事](https://graphql.org/blog/2018-11-06-linux-foundation-graphql/)）、以後の仕様策定は特定企業から切り離されたGraphQL Foundationで進んでいます。

## スキーマ・クエリ・ミューテーションの基本と最小のコード例

ユーザーと投稿を扱う小さな例で書き分けます。リアルタイム配信のサブスクリプションも操作の1つで、実装は[GraphQLサブスクリプションとgraphql-wsでの実装](/tech/details/16306/)で扱っています。

### スキーマで型とエントリポイントを定義する書き方

```
type Query {
  user(id: ID!): User
}

type User {
  id: ID!
  name: String!
  posts(first: Int = 10): [Post!]!
}

type Post {
  title: String!
}
```

`Query`型が問い合わせの入口で、`!`はnullを許さない型、`[Post!]!`は「空配列は許すが、配列自体も各要素もnullにはできない投稿の配列」です。`posts`には件数を受け取る引数`first`を付け、既定値を10にしています。null許容や命名の決め方で後の運用が大きく変わるため、設計の判断は[GraphQLスキーマ設計のベストプラクティス](/tech/details/8355/)にまとめています。

### クエリで必要なフィールドだけを指定する書き方

```
query GetUser {
  user(id: "1") {
    name
    posts {
      title
    }
  }
}
```

応答は`{"data":{"user":{"name":"山田","posts":[...]}}}`の形で返り、スキーマにある`id`は書いていないので含まれません。同じフィールドの組を複数のクエリで使い回すなら[GraphQLのFragment（フラグメント）](/tech/details/9660/)で部品化できます。

### ミューテーションと変数でデータを更新する書き方

```
mutation CreatePost($input: CreatePostInput!) {
  createPost(input: $input) {
    title
  }
}

# variables（クエリとは別のJSONで送る）
{ "input": { "userId": "1", "title": "はじめての投稿" } }
```

更新はミューテーションで書き、値はクエリ本文に埋め込まず変数として別に渡します（[公式 Mutations](https://graphql.org/learn/mutations/)）。本文が固定されるので、後述の信頼済みドキュメント（許可済みクエリだけを実行する方式）とも組み合わせやすくなります。なお、この例は`Mutation.createPost`と`CreatePostInput`、更新用リゾルバを別途定義したAPI向けの構文例で、本記事の取得専用スキーマと後述のserver.mjsでは実行できません。

## クエリの条件指定：引数・変数・エイリアス・@include/@skipの書き方

「GraphQLで条件を付けて取りたい」ときに使う仕組みは4つあり、どれもSeptember 2025版の仕様で定義されています。SQLのWHERE句のような汎用の検索構文は仕様に無く、どんな条件を受け付けるかはスキーマ側が引数として決めます。

### 引数でIDや件数を指定して絞り込む書き方

仕様は、フィールドを「値を返す関数」と見なし、振る舞いを変える引数を受け取れると定めています（[§2.7 Arguments](https://spec.graphql.org/September2025/#sec-Language.Arguments)）。`user(id: "1")`のIDも、`posts(first: 1)`の件数も引数です。下は先のスキーマに対して投稿を1件だけ取るクエリで、手元で実行すると`{"data":{"user":{"name":"山田","posts":[{"title":"はじめての投稿"}]}}}`が返りました。

```
{
  user(id: "1") {
    name
    posts(first: 1) {
      title
    }
  }
}
```

件数を引数で制限できるようにしておくのは、重いクエリ対策の前提でもあります。GitHubのGraphQL APIは一覧（connection）に`first`か`last`を必須とし、値を1〜100に制限しています（[Rate limits and query limits](https://docs.github.com/en/graphql/overview/rate-limits-and-query-limits-for-the-graphql-api)）。2ページ目以降の取り方はカーソル方式が定番で、選び方は[ページネーション設計（オフセットとカーソルの選び分け）](/tech/details/16297/)で比較しています。

### エイリアスで同じフィールドを別条件で並べて取得する書き方

同じ`user`フィールドを引数違いで2回呼ぶと、応答のキーが衝突します。エイリアスは応答側の名前を付け替える仕組みです（[§2.8 Field Alias](https://spec.graphql.org/September2025/#sec-Field-Alias)）。

```
{
  yamada: user(id: "1") { name }
  sato: user(id: "2") { name }
}
```

実行結果は`{"data":{"yamada":{"name":"山田"},"sato":{"name":"佐藤"}}}`で、1回のリクエストで2人分を取れました。ただしエイリアスを大量に並べれば1リクエストで何百回もリゾルバを呼べるため、本番ではエイリアス数にも上限を設けます。

### 変数と@include・@skipで項目の出し入れを切り替える書き方

画面の状態によって取る項目を変えたいときは、変数とディレクティブを組み合わせます。`@include(if: 真偽値)`は真のときだけ、`@skip(if: 真偽値)`は真のときだけ除いてフィールドを実行します（[§3.13.2 @include](https://spec.graphql.org/September2025/#sec--include)）。

```
query GetUser($id: ID!, $withPosts: Boolean!) {
  user(id: $id) {
    name
    posts @include(if: $withPosts) {
      title
    }
  }
}

# variables
{ "id": "1", "withPosts": false }
```

`withPosts`を`false`で送ると、応答は`{"data":{"user":{"name":"山田"}}}`となり`posts`は消えました。クエリ文字列を組み立て直さずに済むので、文字列連結でクエリを作るコードより安全です。

## リゾルバの仕組み：4つの引数とN+1問題の実測

サーバーは届いたクエリを構文解析し、スキーマで検証し、フィールドごとにリゾルバを呼んで値を集めます（[公式 Execution](https://graphql.org/learn/execution/)）。柔軟さも性能問題も、この「フィールド単位で関数が呼ばれる」構造から生まれます。

### obj・args・context・infoの4引数が受け取る値

リファレンス実装のリゾルバは4つの引数を受け取ります。

| 引数          | 中身                | 使いどころ                |
| ----------- | ----------------- | -------------------- |
| obj（parent） | 親フィールドの戻り値        | User.postsでユーザーIDを得る |
| args        | クエリで渡された引数        | first・idの値           |
| context     | 全リゾルバ共通の値         | ログイン中のユーザー・DB接続      |
| info        | 実行中のフィールドとスキーマの情報 | 高度な最適化               |

認可の判定に使うログインユーザーは`context`に入れて全リゾルバへ配るのが基本形です。GraphQL.jsでリゾルバを省略すると、既定のリゾルバが親オブジェクトの同名プロパティを読み取ります。その値が関数なら、引数・context・infoを渡して呼び出した結果を使います。

### 100件の一覧で101回の問い合わせになるN+1問題とDataLoader

100人のユーザーとそれぞれの投稿を取るクエリを、graphql 17.0.2と模擬DB関数で実行し、データ取得関数の呼び出し回数を数えました。以下の回数は実DBのSQL発行数や通信時間の実測ではありません。`User.posts`のリゾルバがユーザーごとに投稿を取りに行くと、一覧の1回＋100人分で**101回**です。これがN+1問題です。

```
// User.posts のリゾルバ（parent, args, context, info）
resolve: (parent, args, context, info) =>
  context.loader.load(parent.id),

// リクエストごとに作り、同じ処理単位で集まったIDを1回で問い合わせる
const loader = new DataLoader(async (ids) => db.postsByUsers(ids));
// postsByUsersはidsと同じ長さ・順序の配列を返す。各要素はそのIDの投稿配列で、投稿なしは[]。
await graphql({ schema, source, contextValue: { loader } });
```

dataloader 2.2.3で同じ処理単位に集まったIDをまとめて渡すように変えると、回数は**2回**（ユーザー一覧1回＋投稿の一括取得1回）に減りました。DataLoaderは結果をキャッシュするので、ユーザー間でデータが混ざらないよう`context`に載せてリクエストごとに作り直します。ORM側で発行回数を検出する方法は[N+1問題の発行クエリ数の実測と検出方法](/tech/details/4262/)で解説しています。

## REST APIとGraphQLの違い：比較表と同じデータの取得例

RESTはリソースごとのURLとHTTPメソッドで操作する設計スタイルで、原則は[RESTとは？REST APIの仕組みと6原則](/tech/details/13588/)で整理しています。GraphQLとの違いは次の7点です。

| 観点        | REST API         | GraphQL       |
| --------- | ---------------- | ------------- |
| エンドポイント   | リソースごとに複数        | 原則1つ          |
| 返るデータ     | API設計次第で項目選択も可能  | スキーマ内の項目を選択   |
| 関連データの取得  | API設計次第で一括取得可能   | スキーマ内で一括取得可能  |
| HTTPキャッシュ | GETで素直に効く        | POST中心で工夫が要る  |
| エラーの表し方   | HTTPステータス        | 応答のerrors配列が主 |
| 仕様書       | OpenAPI等を別に用意    | スキーマが仕様を兼ねる   |
| 版の管理      | URLに/v2/を切ることが多い | フィールド追加と非推奨化  |

RESTで「ユーザーとその投稿」を出すには`GET /users/1`と`GET /users/1/posts`の2回に分けて取得する設計例を考えます。この例はGraphQLなら前章の`GetUser`クエリ1回にまとめられますが、RESTでも関連データを含めるエンドポイントを設計すれば1回で取得できます。

見落としやすいのはエラーの扱いです。GraphQLでは一部のフィールドが失敗しても、成功した分の`data`と失敗理由の`errors`が同じ応答に入ります。GraphQL over HTTPの仕様案（2026年10月時点でStage 2: Draft）は、`data`がnullでなければ2xxを返すことを必須としているため、HTTPステータスだけを見る監視では失敗を取りこぼします（[Status Codes](https://http-spec.graphql.org/draft/#sec-Status-Codes)）。選定基準や移行コストまで含めた比較は[REST APIとGraphQLの違いと使い分け](/tech/details/3591/)で扱っています。

## Node.jsでGraphQLサーバーを動かす最小手順：graphql 17とgraphql-http

公式リファレンス実装のgraphql（graphql-js）と、GraphQL over HTTPに沿ったサーバー部品graphql-httpで最小構成を作ります。2026年10月27日時点のnpmの最新はgraphql 17.0.2（2026年7月3日公開）とgraphql-http 1.23.1（2026年9月28日公開）です。graphql 17系はNode.js 22・24・25系または26以上（`^22 || ^24 || ^25 || >=26`）を要求するため、Node.js 20の環境では16系（最新16.14.2）に留めます。以下はNode.js 26.5.0で実行しました。

### graphqlとgraphql-httpで書く約40行のserver.mjs

空のディレクトリで`npm init -y`を実行し、package.jsonに`"type": "module"`を加えてから`npm install graphql@17 graphql-http`で依存を入れます。

```
import http from 'node:http';
import { buildSchema } from 'graphql';
import { createHandler } from 'graphql-http/lib/use/http';

// スキーマ（型と入口）
const schema = buildSchema(`
  type Query {
    user(id: ID!): User
  }
  type User {
    id: ID!
    name: String!
    posts(first: Int = 10): [Post!]!
  }
  type Post {
    title: String!
  }
`);

// データ（本番ではDBや他のAPIから取得する）
const users = {
  '1': { id: '1', name: '山田', posts: [{ title: 'はじめての投稿' }, { title: '2本目' }] },
  '2': { id: '2', name: '佐藤', posts: [] },
};

// ルートのリゾルバ：引数を受け取り、postsは件数を受け取る関数として返す
const rootValue = {
  user: ({ id }) => {
    const u = users[id];
    if (!u) return null;
    return { ...u, posts: ({ first }) => u.posts.slice(0, first) };
  },
};

const handler = createHandler({ schema, rootValue });
http.createServer((req, res) => {
  if (req.url.startsWith('/graphql')) return handler(req, res);
  res.writeHead(404).end();
}).listen(4000);
```

`buildSchema`で作ったスキーマでは、`rootValue`やオブジェクトに置いた関数が引数付きで呼ばれます。前章のエイリアスや`@include`の実行結果は、このサーバーに送って得たものです。

### curlによるdata・errors・HTTPステータスの確認

`node server.mjs`で起動し、別のターミナルから送ります。

```
curl -s -w ' HTTP%{http_code}\n' http://localhost:4000/graphql \
  -H "Content-Type: application/json" \
  -H "Accept: application/graphql-response+json" \
  -d '{"query":"{ user(id: \"1\") { name posts { title } } }"}'

# 結果
{"data":{"user":{"name":"山田","posts":[{"title":"はじめての投稿"},{"title":"2本目"}]}}} HTTP200
```

スキーマに無い`email`を指定すると、実行前の検証で弾かれ`{"errors":[{"message":"Cannot query field \"email\" on type \"User\".", ...}]}`だけが返りました。このときのHTTPステータスは`Accept`で変わり、`application/graphql-response+json`では400、`application/json`だけを送ると200でした。仕様案は検証失敗に422を推奨しているので、実装ごとに差がある点を監視設計で織り込みます。存在しないID（`user(id: "9")`）は検証を通るため、`{"data":{"user":null}}`がHTTP 200で返ります。

## GraphQLのメリット・デメリットと実務での対処

### 往復回数・通信量・スキーマの契約で効く3つのメリット

- **往復回数が減る**：複数のRESTエンドポイントを順に呼んでいた画面を1クエリにまとめられる。回線の遅いモバイルほど効く
- **通信量の無駄が減る**：画面で使うフィールドだけを返す
- **スキーマが契約になる**：フロントエンドとバックエンドが同じ型定義を見て並行開発でき、[GraphQL Code Generator](/tech/details/16021/)でTypeScriptの型も生成できる

フィールドの追加は既存のクエリを壊さず、古いフィールドは`@deprecated`で段階的に退役させられるので、URLに版を切る運用も避けやすくなります。

### HTTPキャッシュ・学習コスト・重いクエリというデメリット

エンドポイントが1つでPOST中心のため、CDNやブラウザのHTTPキャッシュはそのままでは効きません。公式の[Performance](https://graphql.org/learn/performance/)は、queryをGETで送り、長いクエリ本文の代わりにハッシュを送る永続化クエリ（persisted queries）を併用する方法を示しています。クライアント側はIDごとにデータを正規化して持つキャッシュが定番で、[Apollo Clientのキャッシュ](/tech/details/3062/)がその代表です。

もう1つは学習コストです。スキーマ設計、リゾルバ、N+1対策、クエリ制限について、チームの経験に応じた学習・設計時間を確保する必要があります。重いクエリ1本でサーバーが詰まる問題は、次のセキュリティ対策と同じ手段で抑えます。

## GraphQLのセキュリティ対策：認可・信頼済みドキュメント・深さ制限の実装順

クエリを自由に書けることは、攻撃者にとっても自由に書けるということです。公式の[Security](https://graphql.org/learn/security/)に沿って、組み込む順に並べます。

1. **フィールド単位の認可**：リゾルバかその手前のビジネスロジック層で、`context`のユーザーに見せてよいかを判定する（[Authorization](https://graphql.org/learn/authorization/)）
2. **信頼済みドキュメント**：自社アプリ専用のAPIなら、事前登録したクエリのIDしか実行しない。未登録のクエリを拒否し、実行可能な操作を事前に審査した範囲へ限定できる
3. **深さ・幅・複雑度の制限**：ネストの段数、エイリアス数、1回に束ねるクエリ数に上限を設け、フィールドの重みで推定コストを計算して超えたら拒否する
4. **重さで数えるレート制限とタイムアウト**：GitHubのユーザー認証では原則1時間5,000ポイントで、一部のEnterprise Cloud関連の認証では10,000ポイントになる。1回の要求は50万ノードまでで、処理が10秒を超えると打ち切られる。方式の比較は[APIレート制限の5方式と429設計](/tech/details/16179/)を参照
5. **イントロスペクションとエラー詳細の制限**：自社専用なら本番でスキーマの問い合わせを止め、内部エラーの詳細は伏せる。公式は無効化だけでは隠しているにすぎないと注意している

認可と深さ・幅・複雑度の制限は公開前に入れます。信頼済みドキュメントは、実行するクエリを事前に管理できる自社アプリ専用APIで採用します。公開後に制限を足すと、既に動いているクライアントのクエリを弾くおそれがあります。

## GraphQLのトレンド：利用率33%と2025年9月の仕様改訂

Postmanの[2025 State of the API Report](https://voyager.postman.com/doc/postman-state-of-the-api-report-2025.pdf)では、利用しているAPIの方式はRESTが93%、Webhooksが50%、WebSocketsが35%、GraphQLが33%でした。RESTを置き換える流れではなく、RESTを土台に画面向けやリアルタイム用途でGraphQLを足す形が主流です。商用APIでも、Shopifyは2024年10月1日にREST Admin APIをレガシー扱いとし、2025年4月1日以降の新規公開アプリにGraphQL Admin APIを必須にしました（[Shopify REST Admin API](https://shopify.dev/docs/api/admin-rest)）。

言語仕様は、2021年10月版以来の改訂となるSeptember 2025 Editionが2025年9月3日付で公開されています（[spec.graphql.org](https://spec.graphql.org/)）。[公式ブログの発表](https://graphql.org/blog/2025-09-08-september-edition/)が挙げた主な変更は次のとおりです。

- **OneOf入力オブジェクト**：`@oneOf`を付けた入力型で、複数の候補のうち1つだけを指定させる（IDかメールアドレスのどちらかで検索、など）
- **Schema Coordinates**：`User.name`のようにスキーマ内の要素を一意に指す書き方の標準化
- 実行ドキュメントへの説明文、非推奨化の対象拡大、Unicode全範囲への対応

リファレンス実装のgraphql-jsは2026年6月15日に17.0.0を出し、Node.js 20のサポートを外しました。複数チームのスキーマを1つに合成する[GraphQLフェデレーション](/tech/details/16181/)も大規模組織で広がっています。サーバーの実装はNode.jsならApollo ServerやGraphQL Yoga、Pythonなら[Strawberry](/tech/details/6582/)、Javaなら[Spring for GraphQL](/tech/details/4575/)、Goならgqlgenが代表です。マネージドで始めるなら[AWS AppSync](/tech/details/15593/)、既存DBからAPIを生成するなら[Hasura](/tech/details/12667/)も候補になります。

## GraphQLを採用する条件と見送る場面：受託開発での判断基準

### 複数クライアントで画面が多いシステムでの採用

Web・iOS・Androidのように複数のクライアントがあり、画面ごとに必要なデータの組み合わせが違うなら、GraphQLを採用します。画面ごとに専用エンドポイントを増やす設計では、画面追加のたびにAPIの実装・テスト・保守が必要になりやすいためです。複数の社内システムや外部SaaSを1つのAPIの裏にまとめたい場合も、スキーマを窓口にできるGraphQLが向きます。画面専用のAPI層を挟む構成との比較は[BFFとAPI Gatewayの違い・採用判断](/tech/details/13212/)で整理しています。

導入は全面置き換えより、既存のRESTを残したまま新しい画面向けにGraphQLの層を足す段階導入を勧めます。最初のスプリントでスキーマと認可の置き場所を決め、DataLoaderと深さ制限を入れてから画面を増やす順にすると、後から性能と安全性を直す手戻りが減ります。

### 単純なCRUDやCDNキャッシュ重視の公開APIでの見送り

次のどれかに当てはまるなら、GraphQLは過剰です。RESTで作ります。

- 管理画面のように、1画面＝1リソースの単純なCRUDが中心
- 不特定多数に公開し、CDNのキャッシュで負荷を逃がしたい
- ファイルのアップロード・ダウンロードが主役
- チームにGraphQLの経験者がおらず、N+1対策とクエリ制限を設計する時間を取れない

よくある失敗は、新しいからという理由でGraphQLを選び、認可もクエリ制限もREST時代の感覚のまま公開してしまうことです。クライアントもサーバーもTypeScriptに閉じているなら、[tRPC](/tech/details/7937/)の方が軽く済む場合もあります。どちらで作るか決めきれない段階からでも、[一創のAPI開発・システム連携](https://www.issoh.co.jp/service/system/api/)で既存システムの構成を見たうえで方式を提案します。

## よくある質問

### GraphQLとSQLの違いは何ですか？

どちらもクエリ言語ですが、相手が違います。SQLはデータベースに対してテーブルの結合や集計を指示する言語で、主にサーバーの内部で使います。GraphQLはクライアントがAPIに対して欲しいデータの形を指示する言語で、裏でSQLを発行するか別のAPIを呼ぶかはリゾルバの実装次第です。GraphQLサーバーが内部でSQLを発行する組み合わせが典型的です。

### GraphQLを使うにはグラフデータベースが必要ですか？

必要ありません。名前のGraphはデータのつながりを指していて、保存先の種類とは無関係です。MySQLやPostgreSQLなどのリレーショナルデータベースでも、既存のREST APIでも、リゾルバを書けばデータ源にできます。

### GraphQLはREST APIの完全な代替ですか？

代替ではありません。GitHubは、外部の開発者向けにREST APIとGraphQL APIの両方を公開しています。公開範囲だけで方式を決めるのではなく、必要な操作やデータ取得の形に応じて選択・併用できます。Postmanの2025年調査でもRESTの利用が93%と大半を占めています。

### GraphQL APIとは何を指しますか？

GraphQLのクエリを受け付けるAPIのことで、多くは`/graphql`のような1つのURLでPOSTを受けます。GitHubなら`https://api.github.com/graphql`がそれにあたり、個人アクセストークンを付けて送れば手元にサーバーが無くても試せます（[Forming calls with GraphQL](https://docs.github.com/en/graphql/guides/forming-calls-with-graphql)）。

### スキーマファーストとコードファーストの違いは？

スキーマファーストは先にSDLで型定義を書いて実装を合わせる方式で、仕様が明確になりフロントエンドと並行開発しやすくなります。コードファーストはプログラムの型やクラスからスキーマを生成する方式で、実装の変更に追従しやすいのが利点です。複数の職種がスキーマをレビューする体制ならスキーマファーストが向きます。

## 関連記事

- [REST APIとGraphQLの違いと使い分け｜選定基準と運用コスト](/tech/details/3591/)
- [GraphQLスキーマ設計のベストプラクティス｜null・命名・ミューテーション・非推奨化の判断基準](/tech/details/8355/)
- [Apollo Clientとは？GraphQLクライアントの使い方とv4の変更点【useQuery/キャッシュ】](/tech/details/3062/)
- [GraphQLフェデレーションとは？サブグラフ合成とルーターの実装・採用判断を解説](/tech/details/16181/)
- [GraphQLサブスクリプションとは？graphql-wsでの実装とスケール設計を解説](/tech/details/16306/)

---

出典: [GraphQLとは？読み方・REST APIとの違いとクエリ・リゾルバの書き方をわかりやすく解説](<https://www.issoh.co.jp/tech/details/2924/>)（株式会社一創）
