API Routes
補足:App Routerを使用している場合は、API Routesの代わりにServer ComponentsまたはRoute Handlersを使用できます。
API Routesは、Next.jsで公開APIを構築するソリューションを提供します。
pages/apiフォルダ内の任意のファイルは/api/*にマッピングされ、pageの代わりにAPIエンドポイントとして扱われます。これらはサーバー側のみのバンドルであり、クライアント側のバンドルサイズを増やしません。
例えば、以下のAPI Routeはステータスコード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 RouteはCORSヘッダーを指定しないため、デフォルトでは同一オリジンのみです。CORSリクエストヘルパーでリクエストハンドラーをラップすることで、この動作をカスタマイズできます。
- API Routeは静的エクスポートでは使用できません。ただし、App Router内のRoute Handlersは使用できます。
- API Routeは
next.config.jsのpageExtensions設定の影響を受けます。
- API Routeは
パラメーター
export default function handler(req: NextApiRequest, res: NextApiResponse) {
// ...
}req:http.IncomingMessageのインスタンスres:http.ServerResponseのインスタンス
HTTPメソッド
API Route内で異なる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 Routeは、入力されるリクエスト(req)を解析する組み込みリクエストヘルパーを提供します:
req.cookies:リクエストで送信されたクッキーを含むオブジェクト。デフォルトは{}です。req.query:クエリ文字列を含むオブジェクト。デフォルトは{}です。req.body:content-typeによって解析されたボディを含むオブジェクト。ボディが送信されない場合はnullです。
カスタム設定
すべてのAPI Routeは、デフォルト設定を変更するconfigオブジェクトをエクスポートできます:
export const config = {
api: {
bodyParser: {
sizeLimit: '1mb',
},
},
// この関数が実行できる最大許容時間を指定します(秒単位)
maxDuration: 5,
}bodyParserは自動的に有効です。ボディをStreamとして、またはraw-bodyで使用したい場合は、これをfalseに設定できます。
自動bodyParsingを無効にする使用例としては、webhookリクエストの生のボディを検証することが考えられます。例えば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 Routeのレスポンスボディが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」「一時的なリダイレクト」です。res.revalidate(urlPath):オンデマンドでページを再検証します。getStaticPropsを使用します。urlPathはstringである必要があります。
レスポンスのステータスコードを設定する
クライアントにレスポンスを返送する場合、レスポンスのステータスコードを設定できます。
次の例は、レスポンスのステータスコードを200(OK)に設定し、JSONレスポンスとしてHello from Next.js!という値のmessageプロパティを返します:
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: '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' })
}
}指定されたパスまたは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' })
}
}TypeScriptの型を追加する
nextからNextApiRequestとNextApiResponseの型をインポートすることで、API Routeをより型安全にできます。さらにレスポンスデータを型指定することもできます:
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 Routes
API Routeは動的ルートをサポートし、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 Routeをキャッチする
API Routeは、括弧内に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 Routes
キャッチオールルートは、パラメーターを二重括弧([[...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 Routeは動的API Routeよりも優先され、動的API RouteはキャッチオールAPI Routeより優先されます。以下の例を参照してください:
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にはマッチしません。
ストリーミングレスポンス
Pages Routerはストリーミングレスポンスとして動作するAPI Routeをサポートしていますが、Next.js 14以降を使用している場合は段階的にApp Routerを採用し、Route Handlersを使用することをお勧めします。
writeHeadを使用して、API Routeからレスポンスをストリーミングする方法は以下の通りです:
import { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-store',
})
let i = 0
while (i < 10) {
res.write(`data: ${i}\n\n`)
i++
await new Promise((resolve) => setTimeout(resolve, 1000))
}
res.end()
}