Next.js はなぜ BFF と相性がいいのか

中級 | 10分 で読める | 2026.06.14

公式ドキュメント

Next.js は BFF になれる

Next.js App Router は、フロントエンドだけでなくサーバ側の処理も同じプロジェクトに持てます。

そのため、ブラウザと外部APIの間に立つBFFとして使いやすいです。

Browser -> Next.js -> External API

認証では、ブラウザには HttpOnly Cookie を持たせ、Next.jsサーバ側がJWTやOAuth access tokenを使って外部APIを呼ぶ構成にできます。

BFF に必要な役割

BFFには、主に次の役割があります。

役割Next.js の機能
認証済みページの表示Server Components
フォーム送信、更新処理Server Actions
API中継Route Handlers
未認証ユーザーの早期リダイレクトMiddleware
Cookie読み取りcookies()、認証ライブラリ

このため、Next.jsはBFFの実装単位として自然に使えます。

Server Components でデータ取得する

Server Components はサーバ側で実行されます。ブラウザではなくサーバでセッションを読み、APIを呼べます。

import { redirect } from "next/navigation";
import { auth } from "@/auth";

export default async function DashboardPage() {
  const session = await auth();
  if (!session) redirect("/login");

  const orders = await fetchOrdersForUser(session.user.id);

  return <OrderList orders={orders} />;
}

この構成では、ブラウザにアクセストークンを渡す必要がありません。

Route Handlers で API 中継する

Route Handlers を使うと、Next.js内にAPIエンドポイントを作れます。

import { NextResponse } from "next/server";
import { auth } from "@/auth";
import { getAccessToken } from "@/lib/server/token";

export async function GET() {
  const session = await auth();
  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const accessToken = await getAccessToken();
  const res = await fetch("https://api.example.com/orders", {
    headers: { Authorization: `Bearer ${accessToken}` },
  });

  return NextResponse.json(await res.json());
}

ブラウザは /api/orders を呼ぶだけです。外部APIのトークンはサーバ側にあります。

Server Actions で更新処理を行う

Server Actions は、フォーム送信などの更新処理をサーバ側関数として書ける機能です。

"use server";

import { auth } from "@/auth";
import { revalidatePath } from "next/cache";

export async function createOrder(formData: FormData) {
  const session = await auth();
  if (!session) throw new Error("Unauthorized");

  await createOrderOnApi({
    userId: session.user.id,
    title: String(formData.get("title")),
  });

  revalidatePath("/dashboard/orders");
}

更新処理がサーバ側にあるため、ブラウザにAPIトークンを持たせずに済みます。

Middleware は最終防衛線ではない

Middleware は、未認証ユーザーを早めにログイン画面へ飛ばす用途に便利です。

import { auth } from "@/auth";

export default auth((req) => {
  if (!req.auth && req.nextUrl.pathname.startsWith("/dashboard")) {
    return Response.redirect(new URL("/login", req.url));
  }
});

ただし、Middlewareだけに認可を任せてはいけません。matcher漏れ、API直叩き、将来の構成変更で抜け道ができる可能性があります。

最終的な認証・認可チェックは、Server Component、Server Action、Route Handlerの中でも行います。

注意: Middleware はUX改善と早期リダイレクトの層です。認可の本体は各サーバ処理の内部に置きます。

Next.js でも BFF にならない構成

Next.jsを使っていても、次のような構成ではBFFとは言いにくくなります。

  • output: "export" で静的書き出ししている
  • ほぼすべてが "use client" コンポーネント
  • ブラウザから外部APIを直接 fetch している
  • access token を localStorage に保存している

この場合、Next.jsを使っていてもSPA時代のトークン問題に戻ります。

まとめ

Next.js App Router は、BFF構成と相性がよいです。

  • Server Components でサーバ側データ取得ができる
  • Server Actions で更新処理をサーバ側に置ける
  • Route Handlers でAPI中継ができる
  • ブラウザにJWTやaccess tokenを渡さない設計にしやすい
  • Middlewareだけに認可を任せない
  • "use client" 中心で外部APIを直接呼ぶならBFFではない

参考リソース

次に読む記事

← 一覧に戻る
PR
PR
PR
PR