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
を無効にするユースケースの1つは、たとえばGitHubからの、Webhookリクエストの生のボディを検証できるようにすることです。
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
)に設定し、値がHello from Next.js!
のmessage
プロパティを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
のbodyは、クライアントが任意のペイロードを含める可能性があるため、any
型です。使用する前に、bodyの型/形状をランタイムで検証する必要があります。
動的な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を段階的に採用し、代わりにRoute Handlersを使用することをお勧めします。
Route Handlersの関数シグネチャは同形であるため、EdgeとNode.jsの両方のランタイムで同じ関数を使用できます。
この情報は役に立ちましたか?