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 に必要な役割

Next.js BFF内でRSCがread、Server Actionsがwrite、Route HandlersがAPI境界を担う構成図

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