テーマの整理:「API レスポンス整形」とは何か
「API レスポンス整形」は、外部 API から返ってきた“生のレスポンス”を、アプリ側で扱いやすい配列・オブジェクトの形に変換するユーティリティのことです。 業務だと、次のような「めんどくさい現実」がよくあります。
- 単体オブジェクトのときもあれば、配列のときもある
- フィールド名がバラバラ(
user_idとuserIdなど) - ネストが深くて、欲しい情報が取り出しづらい
- 余計なフィールドが多くて、画面やロジックには不要
API レスポンス整形ユーティリティは、これらを一度“入口”で整えてしまい、 「アプリ内部では、いつも同じ形の配列として扱えるようにする」ための道具です。
基本コンセプト:「API の都合」から「自分たちの都合の形」に変える
よくある“扱いづらい”レスポンス例
例えば、こんなレスポンスが来るとします。
const apiResponse = {
status: "ok",
data: {
users: [
{ user_id: "1", user_name: "Alice", age: "20" },
{ user_id: "2", user_name: "Bob", age: null },
],
},
meta: {
total: 2,
},
};
JavaScriptアプリ側では、次のように扱いたくなります。
id,name,ageというフィールド名にしたいageは数値にしたい(null は 0 にしたいなど)data.usersというネストを意識したくない
この「API の形」から「アプリの形」に変える処理を、 毎回手書きするのではなく、ユーティリティとしてまとめておくのがポイントです。
ユーティリティ 1:配列化+フィールド名変換+型変換をまとめて行う
ステップの分解
やりたいことはだいたい次の 3 つです。
- 必ず「配列」にする(単体オブジェクトでも配列に包む)
- フィールド名を自分たちの命名規則に揃える
- 型を揃える(文字列 → 数値、文字列 → 真偽値など)
これを一つの流れにまとめたユーティリティを作ります。
toArray ユーティリティ(おさらい)
まず、「配列か単体か分からないもの」を配列に揃える小さなユーティリティです。
function toArray(value) {
if (value == null) return [];
if (Array.isArray(value)) return value;
return [value];
}
JavaScriptフィールド名変換用のマッピング
API のフィールド名と、アプリ側で使いたいフィールド名の対応を定義します。
const userFieldMap = {
user_id: "id",
user_name: "name",
age: "age",
};
JavaScript型変換ルール
前にやった「型変換一括」と同じ考え方で、フィールドごとの型変換ルールを持ちます。
const userTypeMap = {
id: (v) => Number(v),
age: (v) => (v == null ? 0 : Number(v)),
};
JavaScript実装:reshapeUsersResponse
これらを組み合わせて、「API レスポンス整形」ユーティリティを作ります。
function reshapeUsersResponse(apiResponse) {
const rawUsers = apiResponse?.data?.users ?? [];
const usersArray = toArray(rawUsers);
const normalized = usersArray.map((raw) => {
const obj = {};
for (const apiKey in userFieldMap) {
const appKey = userFieldMap[apiKey];
obj[appKey] = raw[apiKey];
}
for (const key in userTypeMap) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const fn = userTypeMap[key];
obj[key] = fn(obj[key]);
}
}
return obj;
});
return normalized;
}
JavaScript重要ポイントの深掘り
ネストをここで“ほどく” apiResponse?.data?.users ?? [] で、 API のネスト構造をここで一度だけ意識し、 以降のコードでは「usersArray」というフラットな配列として扱えるようにしています。
フィールド名変換を一箇所に集約する userFieldMap を使って、API のキーからアプリのキーへ変換しています。 仕様変更(API 側のフィールド名変更)があっても、このマップを直せば済むようにしておくのが大事です。
型変換を“入口”で済ませる userTypeMap を使って、id や age を数値に変換しています。 これをレスポンス整形の中でやっておくと、 アプリ内部では「id は必ず数値」「age は必ず数値」という前提で書けるようになります。
例題 1:API レスポンスを整形して「扱いやすい配列」にする
const apiResponse = {
status: "ok",
data: {
users: [
{ user_id: "1", user_name: "Alice", age: "20" },
{ user_id: "2", user_name: "Bob", age: null },
],
},
meta: {
total: 2,
},
};
const users = reshapeUsersResponse(apiResponse);
console.log(users);
JavaScript出力イメージはこうなります。
[
{ id: 1, name: "Alice", age: 20 },
{ id: 2, name: "Bob", age: 0 },
]
JavaScriptここでのポイントは、
- ネストがほどけて、単純な配列になっている
- フィールド名が
id,name,ageに揃っている - age が数値になっていて、null は 0 に変換されている
というところです。
この形になっていれば、 画面表示・バリデーション・サマリー生成・統計情報生成など、 これまで作ってきたユーティリティをそのまま使えます。
ユーティリティ 2:レスポンスの「成功・失敗」を一緒に扱う
シナリオ
API が失敗したときは、 「配列」ではなく「エラー情報」を返したい。
実装:safeReshapeUsersResponse
function safeReshapeUsersResponse(apiResponse) {
if (!apiResponse || apiResponse.status !== "ok") {
return {
ok: false,
error: apiResponse?.error ?? "API 呼び出しに失敗しました",
users: [],
};
}
const users = reshapeUsersResponse(apiResponse);
return {
ok: true,
error: null,
users,
};
}
JavaScript重要ポイントの深掘り
レスポンス整形と「成功判定」をセットにする 呼び出し側は、 result.ok を見て成功かどうかを判断し、 成功なら result.users を使う、 失敗なら result.error を表示する、 というシンプルな書き方ができます。
失敗時も「users は必ず配列」にしておく 失敗時でも users: [] を返しておくことで、 呼び出し側は「users は必ず配列」という前提で書けます。 この“形の一貫性”が、バグを減らすうえでかなり効いてきます。
ユーティリティ 3:レスポンス整形を「用途ごと」にまとめる
シナリオ
ユーザー API だけでなく、 売上 API、商品 API、ログ API など、複数のエンドポイントがある。
整形関数をまとめたモジュールのイメージ
例えば、こんな感じでまとめておくと分かりやすいです。
export const ApiShape = {
users: {
reshape: reshapeUsersResponse,
safeReshape: safeReshapeUsersResponse,
},
// sales: { reshape: reshapeSalesResponse, ... },
// products: { reshape: reshapeProductsResponse, ... },
};
JavaScript使う側はこう書くだけになります。
const result = ApiShape.users.safeReshape(apiResponse);
if (!result.ok) {
console.error(result.error);
} else {
console.log(result.users);
}
JavaScriptここでのポイントは、
- 「API ごとの整形ロジック」を一箇所に閉じ込めている
- 画面側のコードは「どの API を使うか」だけを意識すればよい
という状態を作っていることです。
API レスポンス整形ユーティリティで意識してほしい重要ポイント
「API の形を、そのままアプリに広げない」
一番大事なのは、 「API のレスポンス構造を、そのままアプリ全体に広げない」という考え方です。
API の都合で、
- フィールド名が変わる
- ネスト構造が変わる
- 型が変わる
といったことは、普通に起こります。
それをアプリ全体に直結させてしまうと、 変更のたびに画面・ロジック・テストが全部壊れます。
レスポンス整形ユーティリティを“防波堤”として置いておくことで、 API の変更は「整形ユーティリティを直すだけ」で済むようになります。
「入口で整形して、内部では“自分たちの形”だけを使う」
API からデータが入ってきた瞬間に、
- 配列化
- フィールド名変換
- 型変換
を済ませてしまい、 それ以降のコードは「整形済みの配列」だけを前提に書く。
この構造にしておくと、
- バリデーション
- サマリー生成
- 統計情報生成
- 可視化用変換
など、他のユーティリティがすべて「同じ形」を前提に動けるようになります。
手を動かして「API レスポンス整形」の感覚をつかむ
次のコードを実行して、
- 生レスポンス
- 整形済み配列
- 成功・失敗の扱い
を体感してみてください。
function toArray(value) {
if (value == null) return [];
if (Array.isArray(value)) return value;
return [value];
}
const userFieldMap = {
user_id: "id",
user_name: "name",
age: "age",
};
const userTypeMap = {
id: (v) => Number(v),
age: (v) => (v == null ? 0 : Number(v)),
};
function reshapeUsersResponse(apiResponse) {
const rawUsers = apiResponse?.data?.users ?? [];
const usersArray = toArray(rawUsers);
const normalized = usersArray.map((raw) => {
const obj = {};
for (const apiKey in userFieldMap) {
const appKey = userFieldMap[apiKey];
obj[appKey] = raw[apiKey];
}
for (const key in userTypeMap) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
const fn = userTypeMap[key];
obj[key] = fn(obj[key]);
}
}
return obj;
});
return normalized;
}
function safeReshapeUsersResponse(apiResponse) {
if (!apiResponse || apiResponse.status !== "ok") {
return {
ok: false,
error: apiResponse?.error ?? "API 呼び出しに失敗しました",
users: [],
};
}
const users = reshapeUsersResponse(apiResponse);
return {
ok: true,
error: null,
users,
};
}
function demo() {
const okResponse = {
status: "ok",
data: {
users: [
{ user_id: "1", user_name: "Alice", age: "20" },
{ user_id: "2", user_name: "Bob", age: null },
],
},
};
const ngResponse = {
status: "error",
error: "認証エラー",
};
console.log("=== OK ===");
console.log(safeReshapeUsersResponse(okResponse));
console.log("=== NG ===");
console.log(safeReshapeUsersResponse(ngResponse));
}
demo();
JavaScriptまとめ:API レスポンス整形ユーティリティで「外の世界の都合を、内側でうまく受け止める」
API レスポンス整形は、 「外部サービスの都合で決まるレスポンス構造を、アプリ内部で扱いやすい配列・オブジェクトに変換するためのユーティリティ」です。
プロジェクトでは、例えばこうまとめておくとよいです。
export const ApiShape = {
users: {
reshape: reshapeUsersResponse,
safeReshape: safeReshapeUsersResponse,
},
// 他のエンドポイントも同様に…
};
JavaScriptそして、
- API 呼び出し直後
- ストアに保存する直前
- 画面に渡す直前
など、「外からデータが入ってくる入口」で必ずこの整形を通す。
そうすると、 アプリ内部は「自分たちの都合の形」だけを意識すればよくなり、 コードが一気に読みやすく・壊れにくくなります。
外の世界は変わる。 だからこそ、入口で“受け止め方”を決めておく——それが API レスポンス整形ユーティリティです。
