APIとは
APIとは、アプリやサービス同士が機能やデータをやり取りするための窓口です。Web開発では、画面側のJavaScriptやスマホアプリがAPIへリクエストを送り、サーバーがレスポンスを返す形でよく使われます。
たとえば、Todoアプリなら「Todo一覧を取得する」「新しいTodoを追加する」「完了状態を更新する」といった操作をAPI経由で行います。
APIを学ぶ時は、次の4つを分けて見ると混乱しにくくなります。
| 見るもの | 役割 |
|---|---|
| エンドポイント | リクエストを送るURL |
| HTTPメソッド | 取得・作成・更新・削除などの操作 |
| リクエスト | クライアントから送る情報 |
| レスポンス | サーバーから返ってくる結果 |
この記事では、その中でも初心者が最初につまずきやすいAPIレスポンスの読み方を扱います。
定義と結論
APIレスポンスは、サーバーがHTTPリクエストに対して返す応答です。中心になる要素は、結果を番号で示すstatus、応答についての付加情報を持つheaders、実際の内容であるbodyです。JSONはbodyに入れられるデータ形式の一つであり、レスポンス全体の名前ではありません。
API調査では、status、headers、bodyを分けて確認してから、画面側の処理を追います。
HTTP/1.1 200 OK ← status
Content-Type: application/json ← headers
{"name":"Ada"} ← body(JSON形式)
なぜ読み分けが必要なのか
画面に「取得できませんでした」とだけ表示されても、原因は一つではありません。URLが違う404、ログイン切れの401、権限不足の403、サーバー障害の500、成功したがJSONの形が想定と違う場合、HTMLをJSONとして解析した場合が考えられます。
これらをすべて「APIが動かない」と呼ぶと、調査範囲が広すぎます。statusで大分類し、headersで形式やキャッシュなどの条件を読み、bodyで具体的なデータやエラーを確認すれば、次に見る場所を決められます。
登場人物とデータの流れ

ブラウザやスマートフォンアプリはクライアントです。クライアントはURL、HTTPメソッド、headers、必要ならbodyを含むリクエストを送ります。サーバーはルーティング、認証・認可、入力検証、処理を行い、レスポンスを返します。ブラウザのFetch APIはそのレスポンスをResponseオブジェクトとしてJavaScriptへ渡し、DevToolsのNetworkパネルは通信内容を観察できるようにします。
流れは次の通りです。
- クライアントがリクエストを送る
- サーバーが処理してstatus・headers・bodyを返す
- Fetch APIがレスポンスを受け取る
- JavaScriptがstatusを確認し、bodyを適切な形式で読む
- 画面へ成功結果またはエラーを表示する
通信の失敗とHTTP上の失敗は区別します。DNS障害や接続拒否ではレスポンス自体を受け取れません。一方、404や500ではサーバーからレスポンスを受け取っています。
status:処理結果の大分類
HTTP status codeは3桁の番号です。先頭の数字で大まかな種類が分かります。
| 範囲 | 意味 | 代表例 |
|---|---|---|
| 1xx | 処理中の情報 | 100 Continue |
| 2xx | 成功 | 200 OK、201 Created、204 No Content |
| 3xx | 転送・キャッシュ | 301、302、304 |
| 4xx | リクエスト側の条件を満たせない | 400、401、403、404、409、422 |
| 5xx | サーバー側で処理できない | 500、502、503 |
200は一般的な成功、201はリソース作成成功、204は返すbodyがない成功です。400は不正なリクエスト、401は認証が必要または無効、403は認証済みでも操作権限がない状態、404は対象が見つからない状態です。500はサーバー内部の予期しない失敗を表します。
401は「あなたが誰か確認できない」、403は「誰か分かっているが許可できない」と考えると切り分けやすくなります。
ただし、各APIがどのstatusを採用するかはAPI仕様を確認します。たとえば入力エラーに400を使うAPIも422を使うAPIもあります。
headers:応答を読むための付加情報
headersは名前と値の組です。bodyの形式、キャッシュ方針、転送先、Cookie、CORSなどを伝えます。
| header | 確認できること |
|---|---|
Content-Type | bodyのメディアタイプと文字コード |
Content-Length | bodyのおおよその長さ |
Cache-Control | キャッシュ可能か、再検証が必要か |
Location | リダイレクト先や作成したリソースの場所 |
Set-Cookie | サーバーが保存を求めるCookie |
Access-Control-Allow-Origin | ブラウザに許可するオリジン |
JSONを期待している時はContent-Type: application/jsonかを確認します。ログイン画面やエラーページへ転送されてtext/htmlが返ると、response.json()で構文エラーになります。CORSのheaderはブラウザがレスポンスをJavaScriptへ公開してよいかを判断する情報であり、認証・認可の代わりではありません。
bodyとJSON
bodyは応答の中身です。JSON、HTML、プレーンテキスト、画像、PDFなどを格納できます。204やHEADリクエストのようにbodyを持たない応答もあります。
JSONは文字列、数値、真偽値、null、配列、オブジェクトを表現できるテキスト形式です。
{
"id": 42,
"title": "学習メモ",
"done": false,
"tags": ["API", "HTTP"]
}
JSONではキーと文字列をダブルクォートで囲み、末尾カンマやコメント、関数、undefinedは使えません。JavaScriptオブジェクトと見た目は似ていますが、同じものではありません。HTTPで届くbodyはバイト列であり、response.json()が読み取りとJSON解析を行ってJavaScriptの値を返します。
Fetch APIでの主要パターン
const response = await fetch("/api/posts");
if (!response.ok) {
const message = await response.text();
throw new Error(`HTTP ${response.status}: ${message}`);
}
const data = await response.json();
fetch()は404や500を受け取っただけでは通常rejectされません。サーバーとのHTTP通信が成立したためです。response.okはstatusが200〜299かを示す便利な値ですが、API固有の成功条件までは判断しません。
bodyを読むメソッドは用途で選びます。
| メソッド | 用途 |
|---|---|
response.json() | JSONとして解析する |
response.text() | 文字列として読む |
response.blob() | 画像などのバイナリを読む |
response.arrayBuffer() | バイト列として扱う |
response.formData() | フォームデータとして読む |
bodyは原則として一度だけ消費します。json()した後に同じレスポンスへtext()を呼ぶと読めません。調査用に両方必要なら、読み方を一つに決めるかResponse.clone()の用途とメモリ負荷を理解して使います。
具体例:保存APIを追う
投稿作成ボタンを押しても画面が変わらないとします。Networkで対象リクエストを選び、次を順番に見ます。
- Request URLとMethodが仕様通りか
- statusが201か、それ以外か
- Response Headersの
Content-Type - Response bodyのエラーコードや作成済みID
- Request Payloadに入力値が含まれるか
statusが422でbodyが次なら、通信やJSON解析ではなく入力検証の問題です。
{
"code": "VALIDATION_ERROR",
"fields": {
"title": "1文字以上で入力してください"
}
}
statusが201で正しいJSONも返っているなら、次は画面側の状態更新やプロパティ名を調べます。レスポンスが正常なら、調査対象を通信からクライアント処理へ移せます。
よくある誤解
status 200ならデータも正しい
空配列、古いキャッシュ、想定と違う構造でも200になり得ます。bodyと要件を確認します。
JSON解析エラーはサーバーのJSON文法ミス
HTMLの404ページ、空body、途中で切れた応答をJSONとして読んだ可能性もあります。先にstatus、Content-Type、生のResponseを見ます。
Consoleだけ見ればよい
Consoleにはアプリが加工したエラーしか出ないことがあります。Networkには実際のrequestとresponseがあります。
CORSエラーならサーバーに届いていない
CORSはブラウザが応答をJavaScriptへ渡す際の制約です。サーバーへ届いている場合もあるため、サーバーログとNetworkを併せて確認します。
注意点とベストプラクティス
- API仕様で成功statusとエラーbodyの形を決める
- エラーbodyには機械判定用コードと利用者向けメッセージを分けて持たせる
- サーバー内部のスタックトレースや秘密情報をbodyへ出さない
Content-Typeを実際のbodyと一致させる- 204を返す時にJSON解析を試みない
- 認証CookieやAuthorization headerをスクリーンショットで共有しない
- 受け取ったJSONを信用せず、利用前に必要な形を検証する
デバッグの確認表
| 観察結果 | 次に見る場所 |
|---|---|
| リクエスト自体がない | イベント、条件分岐、JavaScriptエラー |
(failed)、statusなし | URL、DNS、TLS、接続、CORS表示 |
| 400・422 | Request Payload、入力仕様、bodyの詳細 |
| 401・403 | Cookie、Authorization、期限、権限 |
| 404 | URL、HTTPメソッド、ルート、ID |
| 409 | 重複、現在状態、同時更新 |
| 500台 | サーバーログ、依存サービス、追跡ID |
| 2xxだが表示されない | JSON構造、状態更新、描画条件 |
| JSON解析エラー | status、Content-Type、生body、204か |
DevToolsでは対象通信を選び、Headers、Payload、Response、Timingを確認します。再現時刻、URL、status、エラーbodyを記録すると、サーバーログとも照合しやすくなります。
まとめ
APIレスポンスは、status、headers、bodyから成り、JSONはbodyの形式の一つです。まずstatusで結果を分類し、headersで形式や通信条件を確認し、bodyでデータまたはエラーの詳細を読みます。
「APIが失敗した」ではなく、「どのURLが、何番を返し、どの形式で何が入っていたか」まで言葉にすると、調査は次へ進みます。
参考資料
- MDN: Fetch APIの使用
- MDN: Response
- RFC 9110: HTTP Semantics
- RFC 8259: The JavaScript Object Notation (JSON) Data Interchange Format