発行:
更新:

API Routes (Route Handlers)

Next.js は、画面(フロントエンド)を作るだけでなく、データを配信する API (バックエンド機能) も同じプロジェクト内に作ることができます。
これを Route Handlers と呼びます。

ただ、Next.jsアプリのためのバックエンド作成は 次章で解説する「Server Actions」で行うことが推奨されています。 Server Actions は、 BFF (Backend For Frontend) という思想を体現した機能だからです。とはいえ、Server Actionsだけを学ぶと、便利すぎて魔法のように思えてしまうため、基礎としてAPI Routes の方法でバックエンドのイメージを掴んでおくとより良い歩みになると考え、先に説明する章立てとしてあります。

API ルートの作り方

src/app/api ディレクトリの中に route.ts というファイルを作ると、それが API のエンドポイントになります。

例: src/app/api/hello/route.ts を作れば、http://localhost:3000/api/hello でアクセスできます。

基本的な API のコード

GET リクエストを受け取る簡単な API を作ってみましょう。

src/app/api/hello/route.ts
import { NextResponse } from 'next/server';

export async function GET() {
  return NextResponse.json({ message: 'Hello Next.js API!' });
}

ブラウザで http://localhost:3000/api/hello にアクセスすると、この JSON が返ってきます。
GET の他にも POST, PUT, DELETE などの関数をエクスポートすることで、それぞれの HTTP メソッドに対応できます。

動的ルート (Dynamic Route Handlers)

URL の一部をパラメータとして受け取りたい場合(例: /api/users/123)、画面のルーティングと同じように [slug] のようなディレクトリを作ります。

ファイル作成: src/app/api/users/[id]/route.ts

⚠️ Next.js 15 の注意点

Route Handlersparams も、非同期(Promise)になっています
上記例のコメントで書いた通り、 await を使うとPromise型から値(params)を取り出すことができます。

src/app/api/users/[id]/route.ts
import { NextResponse } from 'next/server';

export async function GET(
  request: Request,
  { params }: { params: Promise<{ id: string }> } // Promise型になる
) {
  // await を使ってPromise型から 値(当例だとid) を取り出せる
  const { id } = await params;

  // 本来はここでDBからユーザー情報を取得したりする
  return NextResponse.json({
    userId: id,
    name: `User ${id}`
  });
}

これで http://localhost:3000/api/users/999 にアクセスすると、{ userId: "999", name: "User 999" } が返ってきます。

クライアントから API を呼ぶ

作った API を、同じプロジェクト内のコンポーネントから呼んでみましょう。
src/app/_components/UserButton.tsx (Client Component) の例です。

src/app/_components/UserButton.tsx
"use client";

import { useState } from "react";

export default function UserButton() {
  const [data, setData] = useState<any>(null);

  const fetchUser = async () => {
    // 自分のサーバーのAPIを呼ぶ
    const res = await fetch('/api/users/100');
    const json = await res.json();
    setData(json);
  };

  return (
    <div className="p-4 border rounded">
      <button
        onClick={fetchUser}
        className="bg-green-500 text-white px-4 py-2 rounded"
      >
        APIを実行
      </button>

      {data && (
        <pre className="mt-4 bg-gray-100 p-2">
          {JSON.stringify(data, null, 2)}
        </pre>
      )}
    </div>
  );
}

まとめ

  • app/api/.../route.ts : API のエンドポイントになる。
  • GET, POST など : 関数名でメソッドを定義する。
  • NextResponse.json() : JSON を返すためのヘルパー。
  • paramsawait : Next.js 15 からの変更点。

これを使えば、データベースへのアクセスや外部サービスの呼び出しなど、サーバー側でしかできない処理を API として隠蔽し、フロントエンドから安全に利用することができます。

冒頭で述べたように、次章では「Server Actions」でのバックエンド実装方法を解説します。クライアント側からサーバー側の処理を呼び出したバックエンドのイメージを持って次章に進んでください。

更新履歴

  • 2025-01-04 : ページのレイアウト崩れ・誤字を修正しました。