1. ホーム
  2. Next.js

【Next.js】Route Handlers(route.ts)でAPIを作る方法|GET・POST を解説

Share

Next.js では、ページを表示するだけでなく、自分でAPI(データを返すエンドポイント)を作ることもできます。App Router でそれを担うのが Route Handlers(ルートハンドラー)です。route.ts というファイルに GETPOST といった関数を書くだけで、フォームの送信先やデータ取得用のURLを用意できます。この記事では、Route Handlers の基本、GET・POST の書き方、リクエストのデータの受け取り方、そして注意点まで、初心者向けに解説します。

Route Handlers とは

Route Handlers は、App Router でAPIエンドポイント(リクエストを受けてデータを返すURL)を作るための仕組みです。app フォルダの中に route.ts というファイルを置き、その中で HTTP メソッドと同じ名前の関数(GETPOSTPUTDELETE など)を export します。すると、そのフォルダのパスがそのままAPIのURLになります。たとえば app/api/hello/route.ts/api/hello というURLで呼び出せます。

GET を作る

まずはデータを返すだけの一番シンプルな例です。GET 関数を export し、Response.json(...) でJSONを返します。

app/api/hello/route.ts
export function GET() {
  // JSON を返す(/api/hello にアクセスすると表示される)
  return Response.json({ message: "こんにちは" });
}

これだけで、ブラウザや fetch から /api/hello にアクセスすると {"message":"こんにちは"} が返ってきます。Response はブラウザ標準のオブジェクトで、Next.js 独自のものではありません。Response.json() を使うと、JSON文字列への変換と適切なヘッダーの設定をまとめて行ってくれます。

クエリパラメータを受け取る

URLの末尾に付く ?name=太郎 のようなクエリパラメータは、引数で受け取る request から読み取れます。request.nextUrl.searchParamsget メソッドで値を取り出します。

app/api/greet/route.ts
import { NextRequest } from "next/server";

export function GET(request: NextRequest) {
  // /api/greet?name=太郎 の「太郎」を取り出す
  const name = request.nextUrl.searchParams.get("name") ?? "ゲスト";
  return Response.json({ message: `ようこそ、${name}さん` });
}

get("name") はパラメータが無ければ null を返すため、?? "ゲスト" で既定値を用意しています。NextRequest はブラウザ標準の Request を拡張したもので、nextUrl のような便利なプロパティが使えます。

POST でデータを受け取る

フォームの送信やデータの登録には POST を使います。送られてきたJSONは、await request.json() で読み取れます。

app/api/users/route.ts
import { NextRequest } from "next/server";

export async function POST(request: NextRequest) {
  // 送信された JSON を受け取る
  const body = await request.json();
  const name = body.name;

  if (!name) {
    // 入力が無ければ 400(Bad Request)を返す
    return Response.json({ error: "name は必須です" }, { status: 400 });
  }

  // ここでデータベースに保存する、などの処理を行う
  return Response.json({ id: 1, name }, { status: 201 });
}

Response.json() の第2引数で status を指定すると、ステータスコードを変えられます。エラーなら 400、作成成功なら 201 のように、状況に合ったコードを返すのが作法です。クライアント側からは、次のように fetch で呼び出します。

client.ts
const res = await fetch("/api/users", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: "太郎" }),
});
const data = await res.json();
console.log(data); // { id: 1, name: "太郎" }

page.tsx と同じフォルダには置けない

Route Handlers を使うときの、つまずきやすいポイントがあります。同じフォルダに page.tsxroute.ts の両方を置くことはできません。どちらも「そのURLへのアクセスに応答する」役割なので、競合してしまうためです。ページとAPIは、app/blog/page.tsx(ページ)と app/api/blog/route.ts(API)のように、別々のパスに分けて配置しましょう。多くのプロジェクトでは、APIを app/api/ 以下にまとめる構成がよく使われます。

まとめ

Route Handlers は、route.tsGETPOST といった関数を書くだけで、Next.js の中にAPIを作れる仕組みです。フォルダのパスがそのままURLになり、Response.json() でJSONを返します。クエリパラメータは request.nextUrl.searchParams、POSTされたJSONは await request.json() で受け取ります。ステータスコードは Response.json() の第2引数で指定できます。ただし、同じフォルダに page.tsxroute.ts を同居させられない点には注意してください。フォームの送信先や外部サービスとの連携口として、まずは小さなAPIから作ってみましょう。

参考ページ