Loading
  • LIGHT

  • DARK

ROUTE

ルートゼロの
アクティビティ

Next.js App Router API連携4パターン徹底比較|最適な選び方は?

2

はじめに|この記事で得られる価値

「Next.js App RouterでAPI連携、どの方法がベスト?」
そんな悩み、現場のエンジニアなら一度は通る道です。
Server ComponentsSWR/React QueryServer Actions…選択肢が増え「これで良いのか?」と迷った経験はありませんか?

特に「fetchはサーバーで?クライアントで?」「Route Handlersはもう不要?」「新機能のCORSやキャッシュ、どう設計すれば?」――後輩レビューや技術選定を任されるほど「自信を持って方針を示せる根拠」が欲しくなりますよね。

本記事は、そんな“現場のモヤモヤ”に寄り添いながら、App Router時代のAPI連携パターン4選徹底比較&FAQ付きで整理します。

・Next.js(App Router)でAPI実装に迷っている
・エラーや設計の“落とし穴”を現場目線で理解したい
・コピペOKの実践コード・FAQまで欲しい
という方におすすめです。

(Next.jsの基礎やAPI設計の全体像については『フロントエンドフレームワーク徹底比較!React・Vue・Angular違いと選び方』もご参照ください)

用語解説:Next.js
ReactベースのWebアプリケーションを高速・柔軟に構築できるフレームワーク。SSRやAPI連携、ルーティング機能が充実。

用語解説:App Router
Next.jsの新しいルーティング方式。ページ・API・UIの構成を柔軟に管理でき、Server ComponentsやServer Actionsなど最新機能と連携。

用語解説:API連携
外部サービスや自社サーバーとデータをやり取りする仕組み。fetchやAxiosなどのHTTPクライアントを使う。

用語解説:Server Components
サーバー側でレンダリングされるReactコンポーネント。初期表示が高速で、クライアントJSの負荷を軽減。

用語解説:SWR/React Query
Reactで非同期データ取得・キャッシュ・ローディング管理を簡単に実装できるライブラリ。

用語解説:Server Actions
Next.jsの新機能。サーバー上の関数を直接呼び出し、フォーム送信やデータ更新を型安全に実装できる。

用語解説:Route Handlers
Next.jsでAPIエンドポイントを定義する仕組み。外部サービス連携やWebhook受信などに利用。

用語解説:fetch
JavaScript標準のHTTPリクエストAPI。サーバー・クライアント両方で利用可能。

用語解説:CORS
異なるドメイン間でリソースをやり取りする際のセキュリティ制約。API連携時にエラー原因となることが多い。

用語解説:キャッシュ
取得したデータを一時保存し、再取得を高速化する仕組み。fetchやSWR/React Queryで制御可能。


1. 最適なAPI連携は?【フローチャートで一発診断】

本題の前に結論サマリから。
下記フローチャートで、要件に合うAPI連携パターンを瞬時に絞り込めます。

[スタート]
  ↓
[Q1: 主な目的はデータの「取得」か「更新」か?]
  ├── [取得] → [Q2: ユーザー操作に応じた頻繁な再取得が必要か?]
  │             ├── [はい] → (A) Client Components (SWR/React Query)
  │             └── [いいえ] → (B) Server Components (fetch)
  └── [更新] → [Q3: 外部サービス用の公開APIエンドポイントが必要か?]
                ├── [はい] → (C) Route Handlers
                └── [いいえ] → (D) Server Actions
  • (A) Client Components…リアルタイム性重視のダッシュボードUIに
  • (B) Server Components…ブログ等、静的な初回表示に
  • (C) Route Handlers…Webhookや外部API用の明示的なエンドポイントに
  • (D) Server Actions…フォーム送信など、内部完結のデータ更新に

なぜこの診断になるのか?次章から「現場目線の理由」と「実践コード」で深掘りします。


2. どう変わった?App RouterのAPI設計【RSCとServer Actionsの役割】

■ React Server Components(RSC)とは?

サーバーで直接fetchし、HTMLだけをクライアントへ返せます。
バンドルサイズ削減・初期表示の高速化も容易に。

(Reactのサーバー・クライアントの違いについては『ReactのuseStateとuseEffectの違いとは?初心者が実務で迷わない使い分け完全ガイド』もご参照ください)

用語解説:React Server Components(RSC)
サーバーでレンダリングされるReactコンポーネント。クライアント側のJS負荷を減らし、SEOやパフォーマンス向上に貢献。

用語解説:バンドルサイズ
Webアプリの配信時にまとめられるJSやCSSなどのファイル容量。小さいほど表示が速くなる。

■ Server Actionsのインパクト

サーバー上の関数を「直接」呼び出せるRPC的な設計。
フォーム送信等の「更新」処理を、API Route不要&型安全に実装できます。

(型安全なフォーム設計・バリデーションについては『TypeScriptフォームバリデーション徹底比較|Zod・Yup・React Hook Formの違いと選び方』もご参照ください)

用語解説:型安全
プログラムの型(string, numberなど)が正しく扱われることで、バグやエラーを未然に防ぐ設計。

用語解説:RPC
Remote Procedure Callの略。ネットワーク越しにサーバー上の関数を直接呼び出す仕組み。

この2つの登場で、Pages Router時代のAPI連携の常識が一変しました。


3. 主要4パターンを比較!【現場ユースケースで解説】

■ 3.1 Client Components(SWR/React Query):動的UI向け

  • こんなとき最適: チャットや通知、リアルタイム管理画面など即時反応UI
  • メリット: useSWR等のHooksで宣言的にデータ取得。キャッシュやローディング管理も自動
  • デメリット: バンドルサイズ増加(クライアントJS依存)/ライブラリ依存性
  • アンチパターン: 静的な初回表示だけならServer Componentsが高速&省コスト

用語解説:Client Components
クライアント(ブラウザ)側で動作するReactコンポーネント。ユーザー操作に即時反応できる。

用語解説:Hooks
Reactの機能拡張API。useStateやuseEffect、useSWRなど、状態管理や副作用処理を簡単に記述できる。

■ 3.2 Server Components(fetch):シンプル&パフォーマンス最適

  • こんなとき最適: ブログやニュース記事など“静的な初期データ”の表示
  • メリット: async/awaitで自然にデータ取得。超軽量・高速キャッシュ制御が柔軟(next.revalidate
  • デメリット: ユーザー操作による再取得はページ遷移or再読み込みが必要
  • アンチパターン: オートコンプリートなど、即時反応UIには非推奨

用語解説:async/await
JavaScriptの非同期処理を直感的に記述できる構文。API取得やデータ処理で多用される。

用語解説:next.revalidate
Next.jsのキャッシュ制御オプション。指定秒数ごとにデータを再取得し、最新状態を保つ。

■ 3.3 Route Handlers(API Routes):明示的なAPIエンドポイントに

  • こんなとき最適: Webhook受信や、外部アプリへのAPI提供
  • メリット: RESTful設計をNext.jsで実現。Webhookや外部連携の「入り口」にも
  • デメリット: 内部処理のみならServer Actionsの方がシンプル&型安全
  • アンチパターン: ログインユーザーの単純なデータ更新はServer Actionsへ

用語解説:RESTful設計
Web API設計の標準。リソースごとにURLを分け、HTTPメソッド(GET/POSTなど)で操作する。

用語解説:Webhook
外部サービスからの通知やイベントを受け取る仕組み。APIエンドポイントで受信する。

■ 3.4 Server Actions:型安全&モダンなデータ更新

  • こんなとき最適: 問い合わせフォームや「いいね」ボタンなど
  • メリット: サーバー関数を直接呼べる(API Route不要)。useFormState等でエラー・状態管理も型安全。JS無効環境でも送信可
  • デメリット: 設計が新しく最初は学習コストあり。「更新」処理向き
  • アンチパターン: 外部アプリ用の汎用APIはRoute Handlersへ

用語解説:useFormState
Next.jsのフォーム状態管理フック。送信結果やエラーを型安全に扱える。

用語解説:JS無効環境
JavaScriptが無効なブラウザや端末でもフォーム送信が可能な設計。


4. すぐ試せる!【実践コード3選】

■ 4.1 認証(Auth.js)× Server Components

セッション情報をサーバー側で取得し、表示を切り替える鉄板パターン。

(認証・セッション管理の基礎については『Spring Boot×OAuth2認証の全比較!現場で失敗しない選び方とは?』もご参照ください)

import { auth } from '@/auth';

export default async function HomePage() {
  const session = await auth();

  return (
    <div>
      {session?.user ? (
        <h1>ようこそ, {session.user.name}さん</h1>
      ) : (
        <h1>ログインしてください</h1>
      )}
    </div>
  );
}

■ 4.2 ヘッドレスCMS(microCMS)× Server Components

fetchnext.revalidateでISRも手軽。

type Props = { params: { id: string } };

async function getPost(id: string) {
  const res = await fetch(
    `https://YOUR_SERVICE_DOMAIN.microcms.io/api/v1/blog/${id}`,
    {
      headers: { 'X-MICROCMS-API-KEY': process.env.MICROCMS_API_KEY! },
      next: { revalidate: 3600 },
    }
  );
  return res.json();
}

export default async function BlogPostPage({ params }: Props) {
  const post = await getPost(params.id);

  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: post.content }} />
    </article>
  );
}

■ 4.3 Server Actions+Zodで型安全フォーム

入力バリデーション〜エラー表示まで「型安全」にまとめられます。

(TypeScriptやZodによる型安全なバリデーションについては『TypeScriptフォームバリデーション徹底比較|Zod・Yup・React Hook Formの違いと選び方』もご参照ください)

// app/actions.ts
'use server';
import { z } from 'zod';

const FormSchema = z.object({
  email: z.string().email('有効なメールアドレスを入力してください。'),
});

export async function submitForm(prevState: any, formData: FormData) {
  const validatedFields = FormSchema.safeParse({
    email: formData.get('email'),
  });

  if (!validatedFields.success) {
    return { errors: validatedFields.error.flatten().fieldErrors };
  }
  // データベース保存処理など
  return { message: '送信成功!' };
}
// app/contact-form.tsx
'use client';
import { useFormState } from 'react-dom';
import { submitForm } from './actions';

const initialState = { message: null, errors: {} };

export function ContactForm() {
  const [state, dispatch] = useFormState(submitForm, initialState);

  return (
    <form action={dispatch}>
      <input type="email" name="email" />
      {state.errors?.email && <p>{state.errors.email[0]}</p>}
      <button type="submit">送信</button>
      {state.message && <p>{state.message}</p>}
    </form>
  );
}

ぜひコードをコピペして、まずは動かしてみてください。


5. よくある疑問・つまずき【FAQで即解決】

  • Q. CORSエラーはなぜ?どこで起きる?
    Server ComponentsRoute HandlersServer Actionsから外部APIを呼ぶ場合は、サーバー側で実行されるためCORSエラーは発生しません。ハマりやすいのはClient Componentsから外部API直叩きのとき。この場合はRoute
    Handlersで「プロキシAPI」を作り、内部経由にするのが定番です。
    (CORSエラーの原因と対策については『JavaScriptでCORSエラーが出たときの原因と対処法を徹底解説』もご参照ください)
  • Q. Server ActionsがあればRoute Handlersは不要?
    No! 両者の棲み分けは明確。
    Server Actions…Next.jsアプリ内部のUI起点のデータ更新
    Route Handlers…Webhook受信や外部サービス向けAPI
    現場では“両方使い分け”が基本です。
  • Q. Server Actionsで注意すべきセキュリティは?
    CSRFはNext.jsが自動で保護。
    ただし「認可(Authorization)」…つまりそのユーザーが操作してよいかの権限チェックは、開発者自身が必ず実装しましょう。
  • Q. キャッシュ戦略のベストプラクティスは?
    fetchの第2引数で制御。
    cache: 'no-store'…毎回取得
    next: { revalidate: 秒数 }…ISR
    更新後はrevalidatePathrevalidateTagでオンデマンド破棄も可能。

    (APIキャッシュやfetchの使い方については『JavaScriptのAjax完全入門|fetchの使い方・CORSエラーの対処・非同期通信の基本を解説』もご参照ください)
  • Q. ClientとServer Components間のデータ受け渡しは?
    基本はprops経由で「サーバー→クライアント」へ渡します。逆向き(クライアント→サーバー)はServer ActionsやRoute Handlers経由が安全です。

まとめ|App RouterのAPI設計で“一歩先”へ

App Router時代のAPI連携は、4つの主役を理解するのが最短ルート。
Server Components(fetch)…静的ページの基本
Client Components(SWR/React Query)…動的UIで真価発揮
Route Handlers…Webhookや外部API連携の要
Server Actions…型安全&モダンなデータ更新

最初は迷って当然。でも、それぞれの得意領域さえ押さえれば、要件ごとに“迷わず選べる”自分になれます。

Next.jsはこれからも進化が続きます。新しい技術をキャッチアップしながら、現場のパフォーマンスも一緒に磨いていきましょう。

ぜひ一度、手元のプロジェクトで実践してみてください!


もっとルートゼロを知りたいなら

DISCOVER MORE