API 路由
Examples
很高兴知道:如果你使用的是应用路由,则可以使用 服务器组件 或 路由处理程序 而不是 API 路由。
¥Good to know: If you are using the App Router, you can use Server Components or Route Handlers instead of API Routes.
API 路由提供了使用 Next.js 构建公共 API 的解决方案。
¥API routes provide a solution to build a public API with Next.js.
文件夹 pages/api
内的任何文件都会映射到 /api/*
,并将被视为 API 端点而不是 page
。它们只是服务器端打包包,不会增加客户端打包包的大小。
¥Any file inside the folder pages/api
is mapped to /api/*
and will be treated as an API endpoint instead of a page
. They are server-side only bundles and won't increase your client-side bundle size.
例如,以下 API 路由返回状态代码为 200
的 JSON 响应:
¥For example, the following API route returns a JSON response with a status code of 200
:
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 路由 不指定 CORS 标头,这意味着它们仅在默认情况下是同源的。你可以通过使用 CORS 请求助手 封装请求处理程序来自定义此类行为。
¥API Routes do not specify CORS headers, meaning they are same-origin only by default. You can customize such behavior by wrapping the request handler with the CORS request helpers.
-
API 路由不能与 静态导出 一起使用。但是,App Router 中的 路由处理程序 可以。
¥API Routes can't be used with static exports. However, Route Handlers in the App Router can.
-
API 路由将在
next.config.js
中受到pageExtensions
配置 的影响。¥API Routes will be affected by
pageExtensions
configuration innext.config.js
.
-
参数
¥Parameters
export default function handler(req: NextApiRequest, res: NextApiResponse) {
// ...
}
-
req
:http.IncomingMessage 的一个实例¥
req
: An instance of http.IncomingMessage -
res
:http.ServerResponse 的一个实例¥
res
: An instance of http.ServerResponse
HTTP 方法
¥HTTP Methods
要处理 API 路由中的不同 HTTP 方法,你可以在请求处理程序中使用 req.method
,如下所示:
¥To handle different HTTP methods in an API route, you can use req.method
in your request handler, like so:
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 路由提供内置请求助手来解析传入请求 (req
):
¥API Routes provide built-in request helpers which parse the incoming request (req
):
-
req.cookies
- 包含请求发送的 cookie 的对象。默认为{}
¥
req.cookies
- An object containing the cookies sent by the request. Defaults to{}
-
req.query
- 包含 请求参数 的对象。默认为{}
¥
req.query
- An object containing the query string. Defaults to{}
-
req.body
- 包含由content-type
解析的主体的对象,如果没有发送主体,则包含null
¥
req.body
- An object containing the body parsed bycontent-type
, ornull
if no body was sent
自定义配置
¥Custom config
每个 API Route 都可以导出一个 config
对象来更改默认配置,如下所示:
¥Every API Route can export a config
object to change the default configuration, which is the following:
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
。
¥bodyParser
is automatically enabled. If you want to consume the body as a Stream
or with raw-body
, you can set this to false
.
禁用自动 bodyParsing
的一个用例是允许你验证 Webhook 请求的原始正文,例如 来自 GitHub。
¥One use case for disabling the automatic bodyParsing
is to allow you to verify the raw body of a webhook request, for example from GitHub.
export const config = {
api: {
bodyParser: false,
},
}
bodyParser.sizeLimit
是解析主体允许的最大大小,采用 bytes 支持的任何格式,如下所示:
¥bodyParser.sizeLimit
is the maximum size allowed for the parsed body, in any format supported by bytes, like so:
export const config = {
api: {
bodyParser: {
sizeLimit: '500kb',
},
},
}
externalResolver
是一个显式标志,告诉服务器该路由正在由外部解析器(如 express 或 connect)处理。启用此选项将禁用对未解决的请求的警告。
¥externalResolver
is an explicit flag that tells the server that this route is being handled by an external resolver like express or connect. Enabling this option disables warnings for unresolved requests.
export const config = {
api: {
externalResolver: true,
},
}
responseLimit
自动启用,当 API 路由的响应正文超过 4MB 时发出警告。
¥responseLimit
is automatically enabled, warning when an API Routes' response body is over 4MB.
如果你不在无服务器环境中使用 Next.js,并且了解不使用 CDN 或专用媒体主机的性能影响,则可以将此限制设置为 false
。
¥If you are not using Next.js in a serverless environment, and understand the performance implications of not using a CDN or dedicated media host, you can set this limit to false
.
export const config = {
api: {
responseLimit: false,
},
}
responseLimit
还可以采用 bytes
支持的字节数或任何字符串格式,例如 1000
、'500kb'
或 '3mb'
。该值将是显示警告之前的最大响应大小。默认为 4MB。(往上看)
¥responseLimit
can also take the number of bytes or any string format supported by bytes
, for example 1000
, '500kb'
or '3mb'
.
This value will be the maximum response size before a warning is displayed. Default is 4MB. (see above)
export const config = {
api: {
responseLimit: '8mb',
},
}
响应助手
¥Response Helpers
服务器响应对象(通常缩写为 res
)包含一组类似 Express.js 的辅助程序方法,用于改善开发者体验并提高创建新 API 端点的速度。
¥The Server Response object, (often abbreviated as res
) includes a set of Express.js-like helper methods to improve the developer experience and increase the speed of creating new API endpoints.
包含的助手有:
¥The included helpers are:
-
res.status(code)
- 设置状态码的函数。code
必须是有效的 HTTP 状态码¥
res.status(code)
- A function to set the status code.code
must be a valid HTTP status code -
res.json(body)
- 发送 JSON 响应。body
必须是 可序列化对象¥
res.json(body)
- Sends a JSON response.body
must be a serializable object -
res.send(body)
- 发送 HTTP 响应。body
可以是string
、object
或Buffer
¥
res.send(body)
- Sends the HTTP response.body
can be astring
, anobject
or aBuffer
-
res.redirect([status,] path)
- 重定向到指定的路径或 URL。status
必须是有效的 HTTP 状态码。如果未指定,status
默认为 "307" "临时重定向"。¥
res.redirect([status,] path)
- Redirects to a specified path or URL.status
must be a valid HTTP status code. If not specified,status
defaults to "307" "Temporary redirect". -
res.revalidate(urlPath)
- 按需重新验证页面 使用getStaticProps
。urlPath
必须是string
。¥
res.revalidate(urlPath)
- Revalidate a page on demand usinggetStaticProps
.urlPath
must be astring
.
设置响应的状态码
¥Setting the status code of a response
将响应发送回客户端时,你可以设置响应的状态代码。
¥When sending a response back to the client, you can set the status code of the response.
以下示例将响应的状态代码设置为 200
(OK
),并以 JSON 响应的形式返回值为 Hello from Next.js!
的 message
属性:
¥The following example sets the status code of the response to 200
(OK
) and returns a message
property with the value of Hello from Next.js!
as a 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 响应
¥Sending a JSON response
将响应发送回客户端时,你可以发送 JSON 响应,该响应必须是 可序列化对象。在现实世界的应用中,你可能希望根据请求端点的结果让客户端知道请求的状态。
¥When sending a response back to the client you can send a JSON response, this must be a serializable object. In a real world application you might want to let the client know the status of the request depending on the result of the requested endpoint.
以下示例发送带有状态代码 200
(OK
) 和异步操作结果的 JSON 响应。它包含在 try catch 块中,用于处理可能发生的任何错误,捕获适当的状态代码和错误消息并将其发送回客户端:
¥The following example sends a JSON response with the status code 200
(OK
) and the result of the async operation. It's contained in a try catch block to handle any errors that may occur, with the appropriate status code and error message caught and sent back to the 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 响应
¥Sending a HTTP response
发送 HTTP 响应的方式与发送 JSON 响应的方式相同。唯一的区别是响应正文可以是 string
、object
或 Buffer
。
¥Sending an HTTP response works the same way as when sending a JSON response. The only difference is that the response body can be a string
, an object
or a Buffer
.
以下示例发送带有状态代码 200
(OK
) 和异步操作结果的 HTTP 响应。
¥The following example sends a HTTP response with the status code 200
(OK
) and the result of the async operation.
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' })
}
}
重定向到指定的路径或 URL
¥Redirects to a specified path or URL
以表单为例,你可能希望在客户端提交表单后将其重定向到指定的路径或 URL。
¥Taking a form as an example, you may want to redirect your client to a specified path or URL once they have submitted the form.
如果表单提交成功,以下示例将客户端重定向到 /
路径:
¥The following example redirects the client to the /
path if the form is successfully submitted:
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 类型
¥Adding TypeScript types
你可以通过从 next
导入 NextApiRequest
和 NextApiResponse
类型来使你的 API 路由更加类型安全,除此之外,你还可以输入响应数据:
¥You can make your API Routes more type-safe by importing the NextApiRequest
and NextApiResponse
types from next
, in addition to those, you can also type your response data:
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
,因为客户端可能包含任何有效负载。在使用之前,你应该在运行时验证主体的类型/形状。¥Good to know: The body of
NextApiRequest
isany
because the client may include any payload. You should validate the type/shape of the body at runtime before using it.
动态 API 路由
¥Dynamic API Routes
API 路由支持 动态路由,并遵循与 pages/
相同的文件命名规则。
¥API Routes support dynamic routes, and follow the same file naming rules used for 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
的请求将使用以下文本进行响应:Post: abc
。
¥Now, a request to /api/post/abc
will respond with the text: Post: abc
.
捕获所有 API 路由
¥Catch all API routes
通过在括号内添加三个点 (...
),可以扩展 API 路由以捕获所有路径。例如:
¥API Routes can be extended to catch all paths by adding three dots (...
) inside the brackets. For example:
-
pages/api/post/[...slug].js
与/api/post/a
匹配,但也与/api/post/a/b
、/api/post/a/b/c
等匹配。¥
pages/api/post/[...slug].js
matches/api/post/a
, but also/api/post/a/b
,/api/post/a/b/c
and so on.
很高兴知道:你可以使用
slug
以外的名称,例如:[...param]
¥Good to know: You can use names other than
slug
, such as:[...param]
匹配的参数将作为查询参数(示例中的 slug
)发送到页面,并且它始终是一个数组,因此,路径 /api/post/a
将具有以下 query
对象:
¥Matched parameters will be sent as a query parameter (slug
in the example) to the page, and it will always be an array, so, the path /api/post/a
will have the following query
object:
{ "slug": ["a"] }
对于 /api/post/a/b
和任何其他匹配路径,新参数将添加到数组中,如下所示:
¥And in the case of /api/post/a/b
, and any other matching path, new parameters will be added to the array, like so:
{ "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
的请求将使用以下文本进行响应:Post: a, b, c
。
¥Now, a request to /api/post/a/b/c
will respond with the text: Post: a, b, c
.
可选捕获所有 API 路由
¥Optional catch all API routes
通过将参数包含在双括号 ([[...slug]]
) 中,可以将所有路由设为可选。
¥Catch all routes can be made optional by including the parameter in double brackets ([[...slug]]
).
例如,pages/api/post/[[...slug]].js
将匹配 /api/post
、/api/post/a
、/api/post/a/b
等。
¥For example, pages/api/post/[[...slug]].js
will match /api/post
, /api/post/a
, /api/post/a/b
, and so on.
catch all 和可选的 catch all 路由的主要区别在于,使用 Optional 时,不带参数的路由也会被匹配(上例中的 /api/post
)。
¥The main difference between catch all and optional catch all routes is that with optional, the route without the parameter is also matched (/api/post
in the example above).
query
对象如下:
¥The query
objects are as follows:
{ } // 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 路由优先于动态 API 路由,动态 API 路由优先于捕获所有 API 路由。看看下面的例子:
¥Predefined API routes take precedence over dynamic API routes, and dynamic API routes over catch all API routes. Take a look at the following examples:
-
pages/api/post/create.js
- 将匹配/api/post/create
¥
pages/api/post/create.js
- Will match/api/post/create
-
pages/api/post/[pid].js
- 将匹配/api/post/1
、/api/post/abc
等,但不匹配/api/post/create
¥
pages/api/post/[pid].js
- Will match/api/post/1
,/api/post/abc
, etc. But not/api/post/create
-
pages/api/post/[...slug].js
- 将匹配/api/post/1/2
、/api/post/a/b/c
等,但不匹配/api/post/create
、/api/post/abc
¥
pages/api/post/[...slug].js
- Will match/api/post/1/2
,/api/post/a/b/c
, etc. But not/api/post/create
,/api/post/abc
-
Edge API 路由
¥Edge API Routes
如果你想在 Edge Runtime 中使用 API 路由,我们建议逐步采用 App Router 并使用 路由处理程序。
¥If you would like to use API Routes with the Edge Runtime, we recommend incrementally adopting the App Router and using Route Handlers instead.
路由处理程序函数签名是同构的,这意味着你可以对 Edge 和 Node.js 运行时使用相同的函数。
¥The Route Handlers function signature is isomorphic, meaning you can use the same function for both Edge and Node.js runtimes.