APIルート
知っておくと便利: App Router を使用している場合、API ルートの代わりにサーバーコンポーネントまたはルートハンドラーを使用できます。
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!' })
}
知っておくと便利:
- API ルートはCORS ヘッダーを指定しません。つまり、デフォルトでは同一オリジンのみです。この動作は、リクエストハンドラをCORS リクエストヘルパーでラップすることでカスタマイズできます。
- API ルートは静的エクスポートでは使用できません。しかし、App Router のルートハンドラーは使用できます。
- API ルートは
next.config.js
のpageExtensions
設定の影響を受けます。
- API ルートは
パラメーター
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') {
// Process a POST request
} else {
// Handle any other HTTP method
}
}
リクエストヘルパー
API ルートは、受信リクエスト (req
) を解析する組み込みのリクエストヘルパーを提供します。
req.cookies
- リクエストによって送信されたクッキーを含むオブジェクト。デフォルトは{}
。req.query
- クエリ文字列を含むオブジェクト。デフォルトは{}
。req.body
-content-type
によって解析されたボディを含むオブジェクト。ボディが送信されていない場合はnull
。
カスタム設定
すべてのAPIルートは、デフォルト設定を変更するためにconfig
オブジェクトをエクスポートできます。デフォルト設定は次のとおりです。
export const config = {
api: {
bodyParser: {
sizeLimit: '1mb',
},
},
// Specifies the maximum allowed duration for this function to execute (in seconds)
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',
},
}
レスポンスヘルパー
サーバーレスポンスオブジェクト(しばしば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: '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 型の追加
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: '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}`)
}
これで、/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` (empty object)
{ "slug": ["a"] } // `GET /api/post/a` (single-element array)
{ "slug": ["a", "b"] } // `GET /api/post/a/b` (multi-element array)
注意点
- 事前定義された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ランタイムの両方で同じ関数を使用できることを意味します。
役に立ちましたか?