API ルート
知っておくと良いこと: App Router を使用している場合、API ルートの代わりに サーバーコンポーネント または ルートハンドラー を利用できます。
API ルートは Next.js で 公開 API を構築するためのソリューションを提供します。
pages/api
フォルダ内のファイルは /api/*
にマッピングされ、ページ
ではなく API エンドポイントとして扱われます。これらはサーバーサイドのみのバンドルであり、クライアントサイドのバンドルサイズを増加させません。
例えば、次の API ルートはステータスコード 200
で JSON レスポンスを返します:
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
message: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.status(200).json({ message: 'Hello from Next.js!' })
}
export default function handler(req, res) {
res.status(200).json({ message: 'Hello from Next.js!' })
}
知っておくと良いこと:
- API ルートは CORS ヘッダーを指定しないため、デフォルトで 同一オリジンのみ となります。この動作は CORS リクエストヘルパー でリクエストハンドラーをラップすることでカスタマイズ可能です。
- API ルートは 静的エクスポート と一緒に使用できません。ただし、App Router の ルートハンドラー は使用可能です。
- API ルートは
next.config.js
のpageExtensions
設定 の影響を受けます。
パラメーター
export default function handler(req: NextApiRequest, res: NextApiResponse) {
// ...
}
req
: http.IncomingMessage のインスタンスres
: http.ServerResponse のインスタンス
HTTP メソッド
API ルートで異なる HTTP メソッドを処理するには、リクエストハンドラー内で req.method
を使用します:
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
// POST リクエストを処理
} else {
// 他の HTTP メソッドを処理
}
}
export default function handler(req, res) {
if (req.method === 'POST') {
// POST リクエストを処理
} else {
// 他の HTTP メソッドを処理
}
}
リクエストヘルパー
API ルートは受信リクエスト (req
) を解析する組み込みのリクエストヘルパーを提供します:
req.cookies
- リクエストで送信されたクッキーを含むオブジェクト。デフォルトは{}
req.query
- クエリ文字列 を含むオブジェクト。デフォルトは{}
req.body
-content-type
で解析されたボディを含むオブジェクト、またはボディが送信されていない場合はnull
カスタム設定
各 API ルートはデフォルト設定を変更する config
オブジェクトをエクスポートできます。デフォルト設定は以下の通りです:
export const config = {
api: {
bodyParser: {
sizeLimit: '1mb',
},
},
// この関数の実行が許可される最大時間を秒単位で指定
maxDuration: 5,
}
bodyParser
は自動的に有効になります。ボディを Stream
として、または raw-body
で消費したい場合は、これを false
に設定できます。
自動 bodyParsing
を無効にする使用例の1つは、GitHub からのもの など、ウェブフック リクエストの生ボディを検証できるようにすることです。
export const config = {
api: {
bodyParser: false,
},
}
bodyParser.sizeLimit
は解析されるボディの最大サイズで、bytes がサポートする任意の形式で指定できます:
export const config = {
api: {
bodyParser: {
sizeLimit: '500kb',
},
},
}
externalResolver
は、このルートが express や connect などの外部リゾルバーによって処理されていることをサーバーに明示的に伝えるフラグです。このオプションを有効にすると、未解決のリクエストに対する警告が無効になります。
export const config = {
api: {
externalResolver: true,
},
}
responseLimit
は自動的に有効になり、API ルートのレスポンスボディが 4MB を超えると警告を表示します。
サーバーレス環境以外で Next.js を使用しており、CDN や専用メディアホストを使用しない場合のパフォーマンス影響を理解している場合、この制限を false
に設定できます。
export const config = {
api: {
responseLimit: false,
},
}
responseLimit
は bytes
がサポートするバイト数または任意の文字列形式(例: 1000
, '500kb'
, '3mb'
)も受け取れます。
この値は警告が表示される前の最大レスポンスサイズとなります。デフォルトは 4MB です(上記参照)。
export const config = {
api: {
responseLimit: '8mb',
},
}
レスポンスヘルパー
サーバーレスポンスオブジェクト(res
と略されることが多い)には、開発者体験を向上させ、新しい API エンドポイントの作成速度を高める Express.js 風のヘルパーメソッドが含まれています。
含まれるヘルパーは次の通りです:
res.status(code)
- ステータスコードを設定する関数。code
は有効な HTTP ステータスコード でなければなりませんres.json(body)
- JSON レスポンスを送信。body
は シリアライズ可能なオブジェクト でなければなりませんres.send(body)
- HTTP レスポンスを送信。body
はstring
、object
またはBuffer
が可能res.redirect([status,] path)
- 指定されたパスまたは URL にリダイレクト。status
は有効な HTTP ステータスコード でなければなりません。指定しない場合、status
はデフォルトで "307" "一時リダイレクト" になりますres.revalidate(urlPath)
-getStaticProps
を使用して オンデマンドでページを再検証。urlPath
はstring
でなければなりません
レスポンスのステータスコードを設定
クライアントにレスポンスを返す際、レスポンスのステータスコードを設定できます。
次の例では、レスポンスのステータスコードを 200
(OK
) に設定し、message
プロパティに Hello from Next.js!
という値を含む JSON レスポンスを返しています:
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
message: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.status(200).json({ message: 'Hello from Next.js!' })
}
export default function handler(req, res) {
res.status(200).json({ message: 'Hello from Next.js!' })
}
JSON レスポンスを送信
クライアントにレスポンスを返す際、JSON レスポンスを送信できます。これは シリアライズ可能なオブジェクト でなければなりません。 実際のアプリケーションでは、リクエストされたエンドポイントの結果に応じて、クライアントにリクエストの状態を知らせたい場合があるでしょう。
次の例では、ステータスコード 200
(OK
) と非同期操作の結果を含む JSON レスポンスを送信しています。エラーが発生した場合に適切なステータスコードとエラーメッセージをクライアントに返すため、try catch ブロック内に含まれています:
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
const result = await someAsyncOperation()
res.status(200).json({ result })
} catch (err) {
res.status(500).json({ error: 'failed to load data' })
}
}
export default async function handler(req, res) {
try {
const result = await someAsyncOperation()
res.status(200).json({ result })
} catch (err) {
res.status(500).json({ error: 'failed to load data' })
}
}
HTTP レスポンスを送信
HTTP レスポンスの送信は JSON レスポンスの送信と同じように機能します。唯一の違いは、レスポンスボディが string
、object
または Buffer
のいずれかでも可能な点です。
次の例では、ステータスコード 200
(OK
) と非同期操作の結果を含む HTTP レスポンスを送信しています。
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
try {
const result = await someAsyncOperation()
res.status(200).send({ result })
} catch (err) {
res.status(500).send({ error: 'failed to fetch data' })
}
}
export default async function handler(req, res) {
try {
const result = await someAsyncOperation()
res.status(200).send({ result })
} catch (err) {
res.status(500).send({ error: 'failed to fetch data' })
}
}
指定されたパスまたは URL にリダイレクト
フォームを例にとると、クライアントがフォームを送信した後、指定されたパスまたは URL にリダイレクトさせたい場合があるでしょう。
次の例では、フォームが正常に送信された場合、クライアントを /
パスにリダイレクトしています:
import type { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { name, message } = req.body
try {
await handleFormInputAsync({ name, message })
res.redirect(307, '/')
} catch (err) {
res.status(500).send({ error: 'Failed to fetch data' })
}
}
export default async function handler(req, res) {
const { name, message } = req.body
try {
await handleFormInputAsync({ name, message })
res.redirect(307, '/')
} catch (err) {
res.status(500).send({ error: 'failed to fetch data' })
}
}
TypeScript 型を追加
next
から NextApiRequest
と NextApiResponse
型をインポートすることで、API ルートをより型安全にできます。加えて、レスポンスデータの型も指定できます:
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
message: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.status(200).json({ message: 'Hello from Next.js!' })
}
知っておくと良いこと:
NextApiRequest
のボディはany
型です。クライアントが任意のペイロードを含む可能性があるためです。使用前にボディの型/形状をランタイムで検証する必要があります。
動的 API ルート
API ルートは 動的ルート をサポートしており、pages/
と同じファイル命名規則に従います。
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const { pid } = req.query
res.end(`Post: ${pid}`)
}
export default function handler(req, res) {
const { pid } = req.query
res.end(`Post: ${pid}`)
}
これで、/api/post/abc
へのリクエストは Post: abc
というテキストで応答します。
キャッチオール API ルート
API ルートは括弧内に3つのドット (...
) を追加することで、すべてのパスをキャッチするように拡張できます。例えば:
pages/api/post/[...slug].js
は/api/post/a
だけでなく、/api/post/a/b
、/api/post/a/b/c
などにもマッチします。
知っておくと良いこと:
slug
以外の名前も使用可能です。例:[...param]
マッチしたパラメーターはクエリパラメーター(例では slug
)としてページに送信され、常に配列になります。したがって、パス /api/post/a
の query
オブジェクトは次のようになります:
{ "slug": ["a"] }
/api/post/a/b
や他のマッチするパスの場合、新しいパラメーターが配列に追加されます:
{ "slug": ["a", "b"] }
例:
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const { slug } = req.query
res.end(`Post: ${slug.join(', ')}`)
}
export default function handler(req, res) {
const { slug } = req.query
res.end(`Post: ${slug.join(', ')}`)
}
これで、/api/post/a/b/c
へのリクエストは Post: a, b, c
というテキストで応答します。
オプショナルキャッチオール API ルート
キャッチオールルートはパラメーターを二重括弧 ([[...slug]]
) で囲むことでオプションにできます。
例えば、pages/api/post/[[...slug]].js
は /api/post
、/api/post/a
、/api/post/a/b
などにマッチします。
キャッチオールとオプショナルキャッチオールルートの主な違いは、オプショナルの場合、パラメーターなしのルート (/api/post
) もマッチすることです。
query
オブジェクトは次のようになります:
{ } // GET `/api/post` (空のオブジェクト)
{ "slug": ["a"] } // `GET /api/post/a` (単一要素の配列)
{ "slug": ["a", "b"] } // `GET /api/post/a/b` (複数要素の配列)
注意点
- 事前定義された API ルートは動的 API ルートよりも優先され、動的 API ルートはキャッチオール API ルートよりも優先されます。以下の例を参照してください:
pages/api/post/create.js
-/api/post/create
にマッチpages/api/post/[pid].js
-/api/post/1
、/api/post/abc
などにマッチ。ただし/api/post/create
にはマッチしないpages/api/post/[...slug].js
-/api/post/1/2
、/api/post/a/b/c
などにマッチ。ただし/api/post/create
、/api/post/abc
にはマッチしない
Edge API ルート
Edge Runtime で API ルートを使用したい場合、App Router を段階的に採用し、ルートハンドラー を使用することを推奨します。
ルートハンドラーの関数シグネチャは同型 (isomorphic) であり、Edge と Node.js ランタイムの両方で同じ関数を使用できます。