API Routes
Examples
Good to know: App Router を使用している場合、 API Routes の代わりにServer ComponentsまたはRoute Handlersを使用することができます。
API routes は、Next.js を使用してpublic APIを build するための解決策を提供します。
フォルダpages/api
内の任意のファイルは/api/*
にマップされ、page
ではなく、API エンドポイントとして扱われます。これらは server-side のみのバンドルであり、Client サイドのバンドルの size を増加させることはありません。
たとえば、次の API route は、ステータス code が200
の JSON response を返します:
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!' })
}
Good to know:
- API RoutesCORS headers を指定しないでください は、オリジンのみが default という意味で、そのような振る舞いは request handler をCORS request ヘルパー でラップすることでカスタマイズできます。
- API Routes はstatic exportsと一緒に使うことはできません。しかし、App Router 内のRoute Handlersは可能です。
- API Routes は、
pageExtensions
設定がnext.config.js
に影響を与えます。
- API Routes は、
Parameters
export default function handler(req: NextApiRequest, res: NextApiResponse) {
// ...
}
req
: http.IncomingMessage のインスタンスres
: http.ServerResponse のインスタンス
HTTP Methods
さまざまな HTTP methods を API route で処理するためには、あなたの request handler で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
}
}
export default function handler(req, res) {
if (req.method === 'POST') {
// Process a POST request
} else {
// Handle any other HTTP method
}
}
Request Helpers
API Routes は、受信する request (req
)を解析する組み込みの request ヘルパーを提供します:
req.cookies
- request から送信された cookies を含む object。default は{}
ですreq.query
- query string を含む object。 default は{}
req.body
-content-type
によって解析された本文を含む object、または本文が送信されていない場合はnull
カスタム config
全ての API Route はconfig
の object を export して、default の設定を変更できます。それは次のようなものです:
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 から のように、webhookの request の原文を検証するためです。
export const config = {
api: {
bodyParser: false,
},
};
bodyParser.sizeLimit
は、パースされたボディの最大 size で、bytes がサポートするすべての形式で次のように設定されます:
export const config = {
api: {
bodyParser: {
sizeLimit: "500kb",
},
},
};
externalResolver
は、明示的なフラグで、この route が express や connect などの外部のリゾルバーによって処理されていることを server に通知します。このオプションを有効にすると、解決されない Request に対する警告が無効になります。
export const config = {
api: {
externalResolver: true,
},
};
responseLimit
は自動的に有効化され、API ルートの response ボディが 4MB を超えた時に警告します。
あなたが server レス環境で Next.js を使っていない、そして CDN を使わない、または専用のメディア host を使わないことのパフォーマンスへの影響を理解しているのであれば、この制限をfalse
に設定することができます。
export const config = {
api: {
responseLimit: false,
},
};
responseLimit
はbytes
がサポートする任意の string フォーマット(例:'1000
'、'500kb'
または'3mb'
)やバイト数を使用することもできます。この value は警告が表示される前の最大の応答サイズになります。Default は 4MB です。(上記参照)
export const config = {
api: {
responseLimit: "8mb",
},
};
Response Helpers
Server Response object (通常は res
と略されます)には、Express.js のようなヘルパーメソッドのセットが含まれており、開発者の経験を向上させ、新しい API エンドポイントの作成速度を向上させます。
含まれているヘルパーは次のとおりです:
res.status(code)
- ステータス code を設定する関数。code
は有効な HTTP ステータス code でなければなりません。res.json(body)
- JSON response を送信します。body
はシリアライズ可能な object でなければなりません。res.send(body)
- HTTP response を送信します。body
はstring
、object
、またはBuffer
のいずれかである可能性があります。res.redirect([status,] path)
- 指定された path または URL への Redirects 。status
は有効なHTTP ステータス code でなければならない。指定されていない場合、status
は "307" "一時的なリダイレクト"に default 設定される。res.revalidate(urlPath)
-getStaticProps
を使用して、Revalidate を要求に応じてページで行う。urlPath
はstring
でなければなりません。
response のステータス code を設定する
client に対して response を送り返す際に、その response のステータス code を設定することができます。
次の例では、''response''のステータス''code''を200
(OK
)に設定し、''value''がHello from Next.js!
であるmessage
プロパティを返し、これを''JSON response''として返します。
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 response を送信する
client に response を返すときは、JSONresponse を送ることができます。これはシリアライズ可能な object でなければなりません。実際のワールドアプリケーションでは、要求されたエンドポイントの結果に応じて request の状況を client に知らせたくなるかもしれません。
次の例では、ステータス code200
(OK
)と async 操作の結果を含む JSON response を送信します。これは try catch ブロック内に含まれており、発生する可能性がある error を処理し、適切なステータス code および error message を捕捉して client に返送します。
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 response を送信する
HTTP response の送信は JSON response の送信と同じ方法で動作します。唯一の違いは response 本文がstring
、object
、またはBuffer
になることができる点です。
次の例は、ステータス code 200
(OK
) と async 操作の結果を持つ HTTP response を送信します。
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' })
}
}
Redirects は特定の path または URL に Redirect します
フォームを例に取ると、client がフォームを提出した後、指定された path または URL に redirect したい場合があります。
次の例では、redirects で client を成功裏にフォームが送信された場合の path /
に Redirect します:
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 type を追加する
あなたは NextApiRequest
と NextApiResponse
type を next
からインポートすることで、あなたの API Routes をより型安全にすることができます。それに加えて、response データにも型を付けることができます:
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!" });
}
Good to know:
NextApiRequest
のボディはany
となっています。これは、 client が任意のペイロードを含める可能性があるためです。それを使用する前に runtime でボディのタイプ/形状を検証するべきです。
Dynamic API Routes
API Routes はdynamic routesをサポートし、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
への request は、Post: abc
というテキストで応答します。
Catch all API routes
API Routes は、括弧の中に三つのドット(...
)を追加することで catch all paths に拡張することができます。例えば:
pages/api/post/[...slug].js
は/api/post/a
に一致しますが、/api/post/a/b
、/api/post/a/b/c
なども対応しています。
Good to know:
slug
以外の名前も使用できます。例えば:[...param]
マッチしたパラメータは、クエリパラメータとして(例ではslug
)ページに送信され、常に配列になります。したがって、path/api/post/a
は、次のようなquery
object を持つことになります。
{ "slug": ["a"] }
そして、/api/post/a/b
の場合や他の一致する path の場合には、新しいパラメータが配列に追加されます。以下のようになります:
{ "slug": ["a", "b"] }
For example:
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
への request に対しては、テキスト:Post: a, b, c
と応答します。
オプションの catch all API routes
Catch all routes は、二重括弧 ([[...slug]]
)でパラメータを含めることにより、オプションとして設定することが可能です。
例えば、pages/api/post/[[...slug]].js
は、/api/post
、/api/post/a
、/api/post/a/b
などと一致します。
catch all とオプショナルの catch all routes との主な違いは、オプショナルでは、パラメーター無しの route もマッチする点です(上記の例では/api/post
)。
query
Object は次のとおりです:
{ } // 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)
Caveats
- 事前に定義された API routes は dynamic API routes より優先され、dynamic API routes は catch all API routes より優先されます。次の例をご覧ください:
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 Routes
もし API Routes を Edge Runtime で利用したい場合、徐々に App Router を採用し、代わりにRoute Handlersを使用することを推奨します。
Route ハンドラー関数の署名は等形的で、つまり Edge および Node.js runtimes の両方で同じ関数を使用することができます。