API Routes
Next.jsでバックエンドAPIを作成する
基本的なAPI Route
route.ts の作成
app/api/以下にファイルを作成
typescript
// app/api/hello/route.ts
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({
message: 'Hello, World!'
});
}
// アクセス: GET /api/hello
// レスポンス: { "message": "Hello, World!" }プレビュー
GET
/api/hello
{ "message": "Hello, World!" }
HTTPメソッド
複数メソッドの定義
GET, POST, PUT, DELETE など
typescript
// app/api/users/route.ts
import { NextResponse } from 'next/server';
// GET: ユーザー一覧を取得
export async function GET() {
const users = await db.user.findMany();
return NextResponse.json(users);
}
// POST: 新規ユーザー作成
export async function POST(request: Request) {
const body = await request.json();
const user = await db.user.create({
data: body
});
return NextResponse.json(user, { status: 201 });
}プレビュー
GET /api/users → 一覧取得
POST /api/users → 新規作成
PUT /api/users/1 → 更新
DELETE /api/users/1 → 削除
動的API Route
パラメータを受け取る
[id]でURLパラメータを取得
typescript
// app/api/users/[id]/route.ts
import { NextResponse } from 'next/server';
interface Context {
params: { id: string }
}
// GET: 特定ユーザーを取得
export async function GET(
request: Request,
{ params }: Context
) {
const user = await db.user.findUnique({
where: { id: params.id }
});
if (!user) {
return NextResponse.json(
{ error: 'User not found' },
{ status: 404 }
);
}
return NextResponse.json(user);
}
// DELETE: ユーザーを削除
export async function DELETE(
request: Request,
{ params }: Context
) {
await db.user.delete({
where: { id: params.id }
});
return new NextResponse(null, { status: 204 });
}プレビュー
/api/users/[id]/route.ts
// /api/users/123
// → params.id = "123"
リクエストの処理
リクエストボディとクエリパラメータ
様々なデータの取得方法
typescript
// app/api/search/route.ts
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
// クエリパラメータを取得
const { searchParams } = new URL(request.url);
const query = searchParams.get('q');
const limit = searchParams.get('limit') || '10';
// /api/search?q=hello&limit=5
// → query = "hello", limit = "5"
const results = await search(query, parseInt(limit));
return NextResponse.json(results);
}
export async function POST(request: Request) {
// JSONボディを取得
const body = await request.json();
// フォームデータを取得
// const formData = await request.formData();
// const name = formData.get('name');
// ヘッダーを取得
const authHeader = request.headers.get('Authorization');
return NextResponse.json({ received: body });
}プレビュー
// クエリパラメータ
searchParams.get('q')
// JSONボディ
await request.json()
// ヘッダー
request.headers.get('Authorization')
レスポンスの設定
カスタムレスポンス
ステータスコードやヘッダーを設定
typescript
import { NextResponse } from 'next/server';
export async function GET() {
// 基本的なJSONレスポンス
return NextResponse.json({ data: 'value' });
// ステータスコード付き
return NextResponse.json(
{ error: 'Not found' },
{ status: 404 }
);
// カスタムヘッダー
return NextResponse.json(
{ data: 'value' },
{
status: 200,
headers: {
'Cache-Control': 'max-age=3600',
'X-Custom-Header': 'value'
}
}
);
// リダイレクト
return NextResponse.redirect(new URL('/login', request.url));
}プレビュー
200 OK
201 Created
204 No Content
400 Bad Request
404 Not Found
500 Server Error
ミドルウェア
middleware.ts
リクエストをインターセプト
typescript
// middleware.ts (プロジェクトルート)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// 認証チェック
const token = request.cookies.get('token');
if (!token && request.nextUrl.pathname.startsWith('/api/protected')) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
);
}
return NextResponse.next();
}
// 適用するパスを指定
export const config = {
matcher: '/api/:path*'
};プレビュー
// 全てのAPIリクエストの前に実行
// 認証、ログ、レート制限などに使う