jpskill.com
🛠️ 開発・MCP コミュニティ 🔴 エンジニア向け 👤 エンジニア・AI開発者

🛠️ FrontendAPI連携パターン集

frontend-api-integration-patterns

フロントエンドとバックエンドAPIの連携を本番環境向けに最適化し、競合状態やエラー処理、UI状態管理などを効率的に行うSkill。

⏱ MCPサーバー実装 1日 → 2時間

📺 まず動画で見る(YouTube)

▶ 【衝撃】最強のAIエージェント「Claude Code」の最新機能・使い方・プログラミングをAIで効率化する超実践術を解説! ↗

※ jpskill.com 編集部が参考用に選んだ動画です。動画の内容と Skill の挙動は厳密には一致しないことがあります。

📜 元の英語説明(参考)

Production-ready patterns for integrating frontend applications with backend APIs, including race condition handling, request cancellation, retry strategies, error normalization, and UI state management.

🇯🇵 日本人クリエイター向け解説

一言でいうと

フロントエンドとバックエンドAPIの連携を本番環境向けに最適化し、競合状態やエラー処理、UI状態管理などを効率的に行うSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o frontend-api-integration-patterns.zip https://jpskill.com/download/2889.zip && unzip -o frontend-api-integration-patterns.zip && rm frontend-api-integration-patterns.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/2889.zip -OutFile "$d\frontend-api-integration-patterns.zip"; Expand-Archive "$d\frontend-api-integration-patterns.zip" -DestinationPath $d -Force; ri "$d\frontend-api-integration-patterns.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して frontend-api-integration-patterns.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → frontend-api-integration-patterns フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-17
取得日時
2026-05-17
同梱ファイル
1

💬 こう話しかけるだけ — サンプルプロンプト

  • Frontend API Integration Patte を使って、最小構成のサンプルコードを示して
  • Frontend API Integration Patte の主な使い方と注意点を教えて
  • Frontend API Integration Patte を既存プロジェクトに組み込む方法を教えて

これをClaude Code に貼るだけで、このSkillが自動発動します。

📖 Claude が読む原文 SKILL.md(中身を展開)

この本文は AI(Claude)が読むための原文(英語または中国語)です。日本語訳は順次追加中。

Frontend API Integration Patterns

Overview

This skill provides production-ready patterns for integrating frontend applications with backend APIs.

Most frontend issues are not caused by APIs being difficult to call, but by incorrect handling of asynchronous behavior—leading to race conditions, stale data, duplicated requests, and poor user experience.

This skill focuses on correctness, resilience, and user experience, not just making API calls work.


When to Use This Skill

  • Connecting frontend apps (React, React Native, Vue, etc.) to backend APIs
  • Integrating ML/AI endpoints (/predict, /recommend)
  • Handling asynchronous data in UI
  • Fixing stale data, flickering UI, or duplicate requests
  • Designing scalable frontend API layers

Core Patterns

1. API Layer (Separation of Concerns)

Centralize API logic and normalize errors.

export class ApiError extends Error {
  constructor(message, status, payload = null) {
    super(message);
    this.name = "ApiError";
    this.status = status;
    this.payload = payload;
  }
}

export const apiClient = async (url, options = {}) => {
  const res = await fetch(url, {
    headers: { "Content-Type": "application/json" },
    ...options,
  });

  if (!res.ok) {
    let payload = null;
    try {
      payload = await res.json();
    } catch (_) {}

    throw new ApiError(
      payload?.message || "Request failed",
      res.status,
      payload
    );
  }

  // handle empty responses safely (e.g. 204 No Content)
  if (res.status === 204) return null;

  const text = await res.text();
  return text ? JSON.parse(text) : null;
};

2. Race-Safe State Management

Prevent stale responses from overwriting fresh data.

useEffect(() => {
  let cancelled = false;

  const load = async () => {
    try {
      setLoading(true);
      setError(null);

      const result = await getUser();

      if (!cancelled) setData(result);
    } catch (err) {
      if (!cancelled) setError(err.message);
    } finally {
      if (!cancelled) setLoading(false);
    }
  };

  load();

  return () => {
    cancelled = true;
  };
}, []);

Use a cancellation flag for non-fetch async logic. For network requests, prefer AbortController.


3. Request Cancellation (AbortController)

Cancel in-flight requests to avoid memory leaks and stale updates.

useEffect(() => {
  const controller = new AbortController();

  const load = async () => {
    try {
      const data = await getUser({ signal: controller.signal });
      setData(data);
    } catch (err) {
      if (err.name === "AbortError") return;
      setError(err.message);
    }
  };

  load();
  return () => controller.abort();
}, [userId]);

4. Retry with Exponential Backoff

Retry only transient failures (5xx or network errors).

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

const fetchWithBackoff = async (fn, retries = 3, delay = 300) => {
  try {
    return await fn();
  } catch (err) {
    const isAbort = err.name === "AbortError";
    const isHttpError = typeof err.status === "number";
    const isRetryable = !isAbort && (!isHttpError || err.status >= 500);

    if (retries <= 0 || !isRetryable) throw err;

    const nextDelay = delay * 2 + Math.random() * 100;
    await sleep(nextDelay);

    return fetchWithBackoff(fn, retries - 1, nextDelay);
  }
};

5. Debounced API Calls

Avoid excessive API calls (e.g., search inputs).

const useDebounce = (value, delay = 400) => {
  const [debounced, setDebounced] = useState(value);

  useEffect(() => {
    const t = setTimeout(() => setDebounced(value), delay);
    return () => clearTimeout(t);
  }, [value, delay]);

  return debounced;
};

6. Request Deduplication

Prevent duplicate API calls across components.

const inFlight = new Map();

export const dedupedFetch = (key, fn) => {
  if (inFlight.has(key)) return inFlight.get(key);

  const promise = fn().finally(() => inFlight.delete(key));
  inFlight.set(key, promise);
  return promise;
};

Examples

Example 1: ML Prediction with Cancellation

const controllerRef = useRef(null);

const handlePredict = async (input) => {
  controllerRef.current?.abort();
  controllerRef.current = new AbortController();

  try {
    const result = await fetchWithBackoff(() =>
      apiClient("/predict", {
        method: "POST",
        body: JSON.stringify({ text: input }),
        signal: controllerRef.current.signal,
      })
    );

    setOutput(result);
  } catch (err) {
    if (err.name === "AbortError") return;
    setError(err.message);
  }
};

Example 2: Debounced Search

const debouncedQuery = useDebounce(query, 400);

useEffect(() => {
  if (!debouncedQuery) return;

  const controller = new AbortController();

  searchAPI(debouncedQuery, { signal: controller.signal })
    .then(setResults)
    .catch((err) => {
      if (err.name !== "AbortError") {
        setError("Search failed. Please try again.");
      }
    });

  return () => controller.abort();
}, [debouncedQuery]);

Example 3: Optimistic UI Update

const deleteItem = async (id) => {
  const previous = items;

  setItems((curr) => curr.filter((item) => item.id !== id));

  try {
    await apiClient(`/items/${id}`, { method: "DELETE" });
  } catch (err) {
    setItems(previous);
    setError("Delete failed. Please try again.");
  }
};

Best Practices

  • ✅ Centralize API logic in a dedicated layer
  • ✅ Normalize errors using a custom error class
  • ✅ Always handle loading, error, and success states
  • ✅ Use AbortController for request cancellation
  • ✅ Retry only transient failures (5xx)
  • ✅ Use debouncing for input-driven APIs
  • ✅ Deduplicate identical requests

Anti-Patterns

  • ❌ Retrying 4xx errors
  • ❌ No request cancellation (memory leaks)
  • ❌ Race-condition-prone state updates
  • ❌ Swallowing errors silently
  • ❌ Global loading/error state for multiple requests
  • ❌ Calling APIs directly inside components repeatedly

Common Pitfalls

Problem: UI shows stale data Solution: Use cancellation or guard against outdated responses

Problem: Too many API calls on input Solution: Use debouncing + cancellation

Problem: Duplicate requests from multiple components Solution: Use request deduplication

Problem: Server overload during retry Solution: Use exponential backoff

Problem: State updates after component unmount Solution: Use AbortController cleanup


Limitations

  • These examples use vanilla JavaScript patterns; adapt them to your framework's data-fetching library when using React Query, SWR, Apollo, Relay, or similar tools.
  • Do not retry non-idempotent mutations unless the backend provides idempotency keys or another duplicate-safe contract.
  • Do not expose privileged API keys in frontend code; proxy sensitive requests through a backend.

Additional Resources