API 路由
提示:如果你正在使用 App 路由,可以使用服务端组件或 Route Handlers 来替代 API 路由。
API 路由为使用 Next.js 构建公共 API 提供了解决方案。
pages/api 文件夹内的任何文件都会映射到 /api/*,并被视为 API 端点而不是 page。它们仅在服务端打包,不会增加客户端的打包大小。
例如,以下 API 路由返回一个状态码为 200 的 JSON 响应:
- TypeScript
- JavaScript
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!' })
}
提示:
- API 路由不指定 CORS 头,这意味着它们默认仅限同源。你可以通过使用 CORS 请求辅助函数包裹请求处理程序来自定义此行为。
- API 路由不能与静态导出一起使用。但是,App 路由中的 Route Handlers 可以。
- 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,如下所示:
- TypeScript
- JavaScript
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
// 处理 POST 请求
} else {
// 处理任何其他 HTTP 方法
}
}
export default function handler(req, res) {
if (req.method === 'POST') {
// 处理 POST 请求
} else {
// 处理任何其他 HTTP 方法
}
}
请求辅助函数
API 路由提供了内置的请求辅助函数,用于解析传入的请求(req):
req.cookies- 包含请求发送的 cookies 的对象。默认为{}req.query- 包含查询字符串的对象。默认为{}req.body- 包含由content-type解析的请求体的对象,如果没有发送请求体则为null
自定义配置
每个 API 路由都可以导出一个 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 路由的响应体超过 4MB 时会发出警告。
如果你不在无服务器环境中使用 Next.js,并且了解不使用 CDN 或专用媒体主机的性能影响,可以将此限制设置为 false。
export const config = {
api: {
responseLimit: false,
},
}
responseLimit 也可以接受字节数或 bytes 支持的任何字符串格式,例如 1000、'500kb' 或 '3mb'。
此值将是显示警告之前的最大响应大小。默认值为 4MB。(见上文)
export const config = {
api: {
responseLimit: '8mb',
},
}
响应辅助函数
服务器响应对象(通常缩写为 res)包含一组类似 Express.js 的辅助方法,可改善开发者体验并提高创建新 API 端点的速度。
包含的辅助函数有:
res.status(code)- 设置状态码的函数。code必须是有效的 HTTP 状态码res.json(body)- 发送 JSON 响应。body必须是可序列化对象res.send(body)- 发送 HTTP 响应。body可以是string、object或Bufferres.redirect([status,] path)- 重定向到指定的路径或 URL。status必须是有效的 HTTP 状态码。如果未指定,status默认为 "307" "临时重定向"。res.revalidate(urlPath)- 使用getStaticProps按需重新验证页面。urlPath必须是string。
设置响应的状态码
向客户端发送响应时,你可以设置响应的状态码。
以下示例将响应的状态码设置为 200(OK),并将 message 属性的值设置为 Hello from Next.js! 作为 JSON 响应返回:
- TypeScript
- JavaScript
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 响应
向客户端发送响应时,你可以发送 JSON 响应,这必须是一个可序列化对象。 在实际应用中,你可能希望根据请求端点的结果让客户端知道请求的状态。
以下示例使用状态码 200(OK)发送 JSON 响应和异步操作的结果。它包含在 try catch 块中以处理可能发生的任何错误,捕获适当的状态码和错误消息并将其发送回客户端:
- TypeScript
- JavaScript
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 响应
发送 HTTP 响应的方式与发送 JSON 响应相同。唯一的区别是响应体可以是 string、object 或 Buffer。
以下示例使用状态码 200(OK)和异步操作的结果发送 HTTP 响应。
- TypeScript
- JavaScript
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
以表单为例,你可能希望在客户端提交表单后将其重定向到指定的路径或 URL。
以下示例在表单成功提交后将客户端重定向到 / 路径:
- TypeScript
- JavaScript
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' })
}
}