API ルート
知っておくと良い: App Router を使用している場合、API ルートの代わりに Server Components または Route Handlers を使用できます。
API ルートは Next.js で 公開 API を構築するためのソリューションを提供します。
pages/api フォルダ内のファイルは /api/* にマッピングされ、page ではなく 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 の Route Handlers は使用可能です。
- 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 を無効にするユースケースの一つは、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',
},
}レスポンスヘルパー
Server Response オブジェクト(略して 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" "Temporary redirect" になります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 ルート
API ルートを Edge Runtime で使用したい場合、App Router を段階的に採用し、Route Handlers を使用することを推奨します。
Route Handlers の関数シグネチャは同型 (isomorphic) であり、Edge と Node.js ランタイムの両方で同じ関数を使用できます。