如何在 Pages Router 的 API Routes (pages/api) 中处理 HTTP 请求?
在 Next.js 的 Pages Router 中,API Routes 是基于文件系统的路由,位于 pages/api 目录下。
处理 HTTP 请求的核心在于导出一个默认函数(Request Handler),该函数接收两个参数:req (Request) 和 res (Response)。
以下是详细的处理指南:
1. 基本结构
每个 API 路由文件必须导出一个默认函数:
javascript
// pages/api/hello.js
export default function handler(req, res) {
// req: http.IncomingMessage 的实例 (加上了一些预构建的中间件)
// res: http.ServerResponse 的实例 (加上了一些辅助函数)
res.status(200).json({ name: 'John Doe' });
}
2. 处理不同的 HTTP 方法 (GET, POST, PUT, DELETE)
在 Pages Router 中,同一个 API 路由文件处理该路径下的所有 HTTP 方法。你需要通过检查 req.method 来区分逻辑。通常使用 switch 语句或 if/else。
javascript
// pages/api/user.js
export default function handler(req, res) {
const { method } = req;
switch (method) {
case 'GET':
// 处理获取数据的逻辑
res.status(200).json({ id: 1, name: 'User A' });
break;
case 'POST':
// 处理创建数据的逻辑
const data = req.body;
// ... 保存到数据库
res.status(201).json({ success: true, data });
break;
case 'PUT':
// 处理更新逻辑
res.status(200).json({ success: true, message: 'Updated' });
break;
default:
// 处理不支持的方法
res.setHeader('Allow', ['GET', 'POST', 'PUT']);
res.status(405).end(`Method ${method} Not Allowed`);
}
}
3. 获取请求数据 (req)
Next.js 会自动解析常见的请求数据。
获取 URL 参数 (Query Parameters):
用于获取?key=value或动态路由参数。javascript// 访问 /api/search?q=nextjs const { q } = req.query; // q === 'nextjs'获取请求体 (Request Body):
Next.js 默认会自动解析 JSON 格式的 Body。javascript// POST 请求发送 JSON: { "title": "Hello" } const { title } = req.body; // title === 'Hello'获取 Cookies:
javascriptconst cookies = req.cookies; const token = cookies.authToken;获取 Headers:
javascriptconst userAgent = req.headers['user-agent'];
4. 发送响应 (res)
res 对象提供了一系列辅助方法来简化响应发送:
- 设置状态码:
res.status(code) - 发送 JSON:
res.json(object) - 发送文本/Buffer:
res.send(body) - 重定向:
res.redirect(path) - 结束响应 (无内容):
res.end()
示例:
javascript
if (!req.body.name) {
return res.status(400).json({ error: 'Name is required' });
}
5. 动态 API 路由
就像页面路由一样,API 路由也支持动态参数。
文件结构: pages/api/posts/[id].js
代码:
javascript
export default function handler(req, res) {
// req.query 包含 URL 查询参数 和 动态路由参数
const { id } = req.query;
if (req.method === 'GET') {
res.status(200).json({ postId: id, title: `Post #${id}` });
}
}
6. TypeScript 类型支持
如果你使用 TypeScript,Next.js 提供了内置类型 NextApiRequest 和 NextApiResponse。
typescript
// pages/api/hello.ts
import type { NextApiRequest, NextApiResponse } from 'next';
type Data = {
name: string;
};
type Error = {
message: string;
}
export default function handler(
req: NextApiRequest,
res: NextApiResponse<Data | Error>
) {
if (req.method === 'GET') {
res.status(200).json({ name: 'John Doe' });
} else {
res.status(405).json({ message: 'Method not allowed' });
}
}
7. 高级配置 (Config)
有些时候你可能不需要 Next.js 自动解析 Body(例如处理 Webhook 签名验证或文件上传)。你可以导出一个 config 对象来修改默认行为。
javascript
export const config = {
api: {
bodyParser: false, // 禁用默认的 body 解析
// externalResolver: true, // 如果你使用外部服务器解析器
},
};
export default function handler(req, res) {
// 此时 req 是原始的数据流,你需要手动解析
// ...
}
总结
在 Pages Router 的 pages/api 中:
- 文件即路由。
req.method用于区分 GET/POST 等操作。req.body和req.query是获取数据的主要方式。res.status().json()是返回数据的标准方式。