JavaScript | Web API:パフォーマンス・セキュリティ - API 利用のベストプラクティス

JavaScript JavaScript
スポンサーリンク
スポンサーリンク

API 利用のベストプラクティスは「安全・高速・壊れない」を同時に満たす設計

API を使うときに初心者がつまずきやすいのは、
「動くコード」と「正しいコード」の違い です。

API は動くだけなら簡単です。
でも、実際のアプリでは

ネットワークが遅い
レスポンスが壊れている
サーバーが落ちている
ユーザーが連打する
攻撃者が変なデータを送る

こういう“現実の世界”が常に起きます。

API 利用のベストプラクティスとは、
「現実の世界でも壊れない API の使い方」 を身につけることです。

ここでは、初心者が最初に押さえるべきポイントを
例題つきで深掘りしていきます。


API の基本原則:失敗を前提に設計する

API は「成功することもあるし、失敗することもある」

API を叩くとき、初心者がやりがちな誤りは
「成功する前提でコードを書く」 ことです。

例えば、こういうコード。

const res = await fetch("/api/user");
const data = await res.json();
console.log(data.name);
JavaScript

一見普通ですが、実際には

レスポンスが 500 エラー
JSON が壊れている
ネットワークが切れた
タイムアウトした

など、いくらでも失敗します。

だから API 利用の基本は
「成功したらこうする、失敗したらこうする」
を必ず書くことです。

正しい書き方の例(成功・失敗を分ける)

async function fetchUser() {
  try {
    const res = await fetch("/api/user");

    if (!res.ok) {
      throw new Error(`サーバーエラー: ${res.status}`);
    }

    const data = await res.json();
    return data;

  } catch (err) {
    console.error("ユーザー情報の取得に失敗:", err);
    return null;
  }
}
JavaScript

ここで重要なのは、

レスポンスが 200 以外ならエラー扱い
JSON パース失敗も catch で拾う
失敗時は null を返して UI 側で分岐

という「壊れない設計」です。


API のパフォーマンス:無駄なリクエストを減らす

同じ API を何度も叩かない

初心者がよくやるミスは、
「必要以上に API を叩く」 ことです。

例えば、スクロールするたびに API を呼ぶ
ボタン連打で API が連続で飛ぶ
画面遷移のたびに同じデータを取得する

こういうのは、
サーバーにもユーザーにも負担です。

対策:キャッシュ・デバウンス・メモ化

例:検索ボックスで入力のたびに API を叩くのは危険です。

悪い例:

input.addEventListener("input", async () => {
  const res = await fetch(`/api/search?q=${input.value}`);
});
JavaScript

良い例(デバウンスで 300ms 以内の連続入力をまとめる):

let timer;

input.addEventListener("input", () => {
  clearTimeout(timer);
  timer = setTimeout(() => {
    fetch(`/api/search?q=${input.value}`);
  }, 300);
});
JavaScript

これで、
「入力のたびに API」→「落ち着いたタイミングで 1 回だけ」
に変わります。


API のセキュリティ:信頼しない・漏らさない・改ざんさせない

API に送るデータは“絶対に信用しない”

ユーザーが入力した値は、
攻撃者が自由に書き換えられる前提で扱います。

例えば、サーバーに送る前に
フロント側でバリデーションしても、
攻撃者は JavaScript を無視して送信できます。

だから API のセキュリティは

フロントでバリデーション(UX のため)
サーバーでバリデーション(安全のため)

の二段構えが基本です。

API キーをフロントに埋め込まない

初心者がやりがちな危険行為:

const API_KEY = "SECRET_ABC123"; // GitHub に上げてしまう
JavaScript

これは 絶対に NG です。

API キーは必ずサーバー側で扱い、
フロントからは触れないようにします。


API のレスポンス設計:UI とセットで考える

API の結果を UI にどう反映するかが重要

API の結果は、
成功・失敗・読み込み中
の 3 状態を UI に反映する必要があります。

例:ユーザー情報を表示する UI

async function showUser() {
  userBox.textContent = "読み込み中…";

  const user = await fetchUser();

  if (!user) {
    userBox.textContent = "取得に失敗しました。再読み込みしてください。";
    return;
  }

  userBox.textContent = `${user.name} さん`;
}
JavaScript

ここで大事なのは、

読み込み中
成功
失敗

の 3 状態を UI で明確に分けていることです。


API の並列処理:Promise.all で高速化する

独立した API は同時に叩く方が速い

悪い例(直列):

const user = await fetch("/api/user");
const posts = await fetch("/api/posts");
JavaScript

良い例(並列):

const [user, posts] = await Promise.all([
  fetch("/api/user"),
  fetch("/api/posts")
]);
JavaScript

これだけで、
待ち時間が半分になることもある ので、
非同期パフォーマンスの基本テクニックです。


API のタイムアウト:永遠に待たない

fetch はデフォルトで“永遠に待つ”

初心者が知らない落とし穴:

await fetch("/api/slow");
JavaScript

これは、
サーバーが応答しない限り永遠に待ち続けます。

対策:AbortController を使う

const controller = new AbortController();

const timeout = setTimeout(() => controller.abort(), 5000);

try {
  const res = await fetch("/api/slow", { signal: controller.signal });
  const data = await res.json();
} catch (err) {
  console.log("タイムアウトしました");
}

clearTimeout(timeout);
JavaScript

これで
「5 秒以内に返ってこなければ諦める」
という設計ができます。


API 利用のベストプラクティスまとめ

API は「動けばいい」ではなく
「失敗しても壊れない」「無駄に叩かない」「安全に扱う」
という視点で設計する必要があります。

成功・失敗・読み込み中の 3 状態を UI に反映する
レスポンスが壊れていても落ちないように try/catch を使う
Promise.all で並列化して高速化する
デバウンスやキャッシュで無駄なリクエストを減らす
API キーは絶対にフロントに置かない
タイムアウトを設けて永遠に待たない
サーバー側でも必ずバリデーションする

あなたが API を書くときに
「この API、失敗したらどうなる?」
「この API、本当に今必要?」
と一度でも考えられるようになったら、
それはもう“API を叩く人”から“API を設計できる人”への第一歩です。

タイトルとURLをコピーしました