概要
get('/api/chat/') のように HTTP リクエストを送信すると、
まず返ってくるのは 「レスポンスそのもの」 です。
そこから先で、
- body を 文字列として読むのか
- JSON として読むのか
- テストライブラリ側で自動パースされるのか
によって、最終的に扱うデータ形式が変わります。
この記事では、同じ GET /api/chat/ を前提に、
- Fetch API
- chai-http
それぞれで Response の body がどのように変換されていくのかを
4パターンに分けて、順を追って整理します。
前提:サーバーが返すレスポンス(例)
サーバーが次のようなレスポンスを返していると仮定します。
- status:
200 - headers:
Content-Type: application/json; charset=utf-8 - body:
{"data":[{"id":1,"text":"hello"}]}
※ body の実体は JSON文字列 です。
パターン①:Fetch API(res.text() → JSON.parse)
async function patternFetchText() {
// ① HTTPリクエストを送信する
// ② 戻り値は Response オブジェクト
// - status / headers / body(ReadableStream) を持つ
const res = await fetch('/api/chat/'); // res: Response
// ③ res.text() を呼び出す
// - Response.body (ReadableStream) を最後まで読む
// - バイト列を「文字列」として取得する
// ※ この時点で body は消費される(再利用不可)
const text = await res.text(); // text: JSON文字列
// ④ JSONとして扱う場合は手動でパースする
const data = JSON.parse(text); // data: JavaScriptオブジェクト
return data;
}
ポイント
-
res.text()は 常に文字列 - JSON / HTML / text/plain など 形式は保証されない
- JavaScriptオブジェクト化は 開発者の責務
パターン②:Fetch API(res.json())
async function patternFetchJson() {
// ① HTTPリクエストを送信する
// ② 戻り値は Response オブジェクト
// - status / headers / body(ReadableStream) を持つ
const res = await fetch('/api/chat/'); // res: Response
// ③ res.json() を呼び出す
// - Response.body (ReadableStream) を最後まで読む
// - バイト列を文字列に変換する
// - JSON.parse() を内部で実行する
// ※ この時点で body は消費される(再利用不可)
const data = await res.json(); // data: JavaScriptオブジェクト
// ④ data は { data: [...] } のようなオブジェクトになる
return data;
}
ポイント
-
res.json()は 高レベルAPI - 内部で
JSON.parseが実行される - Fetch API は 自動ではパースしない
パターン③:chai-http(response.body:パース済み)
async function patternChaiBody() {
// ① chai-http で HTTPリクエストを送信する
// ② 戻り値は chai-http 独自の response オブジェクト
// - status / headers / text / body などを持つ
const response = await request.get('/api/chat/'); // response: chai-http response
// ③ Content-Type が application/json の場合
// chai-http が内部で JSON.parse を実行する
// response.body はすでに JavaScriptオブジェクト
const data = response.body; // data: JavaScriptオブジェクト
// ④ パース処理は不要
return data;
}
ポイント
- chai-http は テスト用途向けの利便設計
- JSON API 前提で 自動パース
- Fetch API より 抽象度が高い
パターン④:chai-http(response.text → JSON.parse)
async function patternChaiText() {
// ① chai-http で HTTPリクエストを送信する
// ② 戻り値は chai-http 独自の response オブジェクト
// - status / headers / text / body などを持つ
const response = await request.get('/api/chat/');
// ③ response.text は「生のレスポンスボディ(文字列)」
const text = response.text; // text: JSON文字列
// ④ JSONとして扱う場合は手動でパースする
const data = JSON.parse(text); // data: JavaScriptオブジェクト
return data;
}
ポイント
-
response.textは 常に文字列 - Fetch API の
res.text()と同じ役割 -
response.bodyは その上位概念
4パターンの変換フローまとめ(順序修正後)
| パターン | 最初に得るもの | 中間処理 | 最終的に得るもの |
|---|---|---|---|
Fetch res.text()
|
Response(body=ReadableStream) | stream → text → JSON.parse | JavaScriptオブジェクト |
Fetch res.json()
|
Response(body=ReadableStream) | stream → text → JSON.parse(内部) | JavaScriptオブジェクト |
chai response.body
|
chai response | 自動パース | JavaScriptオブジェクト |
chai response.text
|
chai response | text → JSON.parse | JavaScriptオブジェクト |