API Routes
補足: App Routerを使用している場合、API Routesの代わりにサーバーコンポーネントまたはRoute Handlersを使用できます。
API routesは、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!' })
}
補足:
- API RoutesはCORSヘッダーを指定しないため、デフォルトでは同一オリジンのみとなります。CORSリクエストヘルパーでリクエストハンドラーをラップすることで、そのような動作をカスタマイズできます。
- API Routesは静的エクスポートと一緒に使用できません。ただし、App RouterのRoute Handlersは可能です。
- API Routesは、
next.config.js
のpageExtensions
設定の影響を受けます。
- API Routesは、
パラメータ
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メソッドを処理
}
}
リクエストヘルパー
API Routesは、受信リクエスト(req
)を解析する組み込みのリクエストヘルパーを提供します:
req.cookies
- リクエストによって送信されたCookieを含むオブジェクト。デフォルトは{}
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 Routesのレスポンス本文が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!' })
}
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: 'データの読み込みに失敗しました' })
}
}
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: 'データの取得に失敗しました' })
}
}
指定されたパスまたは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: 'データの取得に失敗しました' })
}
}
TypeScriptの型の追加
APIルートをより型安全にするために、next
からNextApiRequest
とNextApiResponse
の型をインポートできます。さらに、レスポンスデータの型も指定できます:
import type { NextApiRequest, NextApiResponse } from 'next'
type ResponseData = {
message: string
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<ResponseData>
) {
res.status(200).json({ message: '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}`)
}
これで、/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(', ')}`)
}
これで、/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`(1要素の配列)
{ "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に段階的に移行し、代わりにルートハンドラを使用することをお勧めします。
ルートハンドラの関数シグネチャは同型であり、Edge環境とNode.js環境の両方で同じ関数を使用できます。