Next.js 的 API 路由允许你在 Next.js 应用程序中创建独立的服务端功能,这些功能可以处理 HTTP 请求并返回 JSON 数据或其他响应。API 路由位于项目中的 pages/api 目录下,每个文件都会映射到一个特定的 API 路径。
基本示例
pages/api/users.js
import type { NextApiRequest, NextApiResponse } from 'next';
// 获取用户列表
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'GET') {
const users = [
{ id: 1, name: 'User 1' },
{ id: 2, name: 'User 2' },
{ id: 3, name: 'User 3' },
];
res.status(200).json(users);
} else if (req.method === 'POST') {
const user = req.body;
// 假设这里有一个数据库连接
// await addUserToDatabase(user);
res.status(201).json({ message: 'User added successfully.' });
} else {
res.setHeader('Allow', ['GET', 'POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
}
-
pages/api/users.js
文件定义了一个 API 路由,它将在/api/users
路径上运行。 -
handler
函数接收两个参数:req
(NextApiRequest 对象,代表 HTTP 请求)和res
(NextApiResponse 对象,代表 HTTP 响应)。 - 当请求方法为 GET 时,函数返回用户列表(这里是一个硬编码的数组,实际应用中可能是从数据库查询)。
- 当请求方法为 POST 时,函数接收请求体中的用户数据,然后添加到数据库(这里只是模拟,实际应用中需要连接数据库)并返回成功消息。
- 如果请求方法不是 GET 或 POST,函数返回 405 方法不允许的错误。
Next.js API 路由默认处理 JSON 响应,但你也可以根据需要返回其他类型的内容。例如,如果你需要返回 HTML,可以使用 res.send 方法。
中间件与请求处理链
Next.js API 路由支持中间件模式,允许你在请求到达最终处理函数之前预处理请求或后处理响应。这可以用来验证请求头、鉴权、日志记录等。
Middleware 示例
假设我们想在所有 API 请求前验证一个 API 密钥:
// pages/api/middleware/authenticate.ts
export function authenticate(req: NextApiRequest, res: NextApiResponse, next: () => void) {
const apiKey = req.headers['x-api-key'];
if (!apiKey || apiKey !== process.env.API_KEY) {
return res.status(401).json({ message: 'Unauthorized' });
}
next();
}
然后,在实际的 API 路由中使用此中间件:
// pages/api/users.js
import { authenticate } as middleware from './middleware/authenticate';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
authenticate(req, res, () => {
// ...原有逻辑
});
}
错误处理
良好的错误处理对于生产级应用至关重要。Next.js API 路由允许你自定义错误处理逻辑。
错误处理示例
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
// 假设这里可能会抛出错误
const result = await fetchDataFromDatabase();
res.status(200).json(result);
} catch (error) {
console.error('Error occurred:', error);
res.status(500).json({ error: 'An error occurred while processing your request.' });
}
}
类型安全
为了增强代码的健壮性和可维护性,利用 TypeScript 进行类型注解是个好习惯。
类型安全示例
// pages/api/users.ts
import type { NextApiRequest, NextApiResponse } from 'next';
type User = {
id: number;
name: string;
};
export default async function handler(req: NextApiRequest, res: NextApiResponse<User[] | { message: string }>) {
// ...
}
与外部服务交互
大多数 API 路由会与外部服务交互,比如数据库、第三方 API 等。这里展示如何使用 axios
发起 HTTP 请求。
首先安装 axios
:
npm install axios
然后在 API 路由中使用:
import axios from 'axios';
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
try {
const response = await axios.get('https://api.example.com/data');
res.status(200).json(response.data);
} catch (error) {
res.status(500).json({ error: 'Failed to fetch data from external service.' });
}
}
定制路由与动态路由
Next.js API 路由不仅限于单一路径,还可以根据需要定制更复杂的路由结构,包括动态路由。
定制路由
如果你需要将多个相关的API端点组织在一起,可以创建子目录。例如,假设你正在构建一个博客API,你可以这样组织:
pages/
api/
blog/
posts.ts # 处理 /api/blog/posts 请求
post/[id].ts # 动态路由,处理 /api/blog/post/:id 请求
动态路由
动态路由允许你捕获URL中的一部分作为参数。在上面的例子中,[id]
是一个动态段,它会被实际的ID值替换。在处理函数中,你可以通过 req.query
访问这些动态参数。
动态路由示例 (pages/api/blog/post/[id].ts
)
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { id } = req.query; // 获取动态ID
if (!id) {
return res.status(400).json({ message: 'Missing post ID' });
}
try {
const post = await getPostById(id as string); // 假设这是从数据库获取文章的函数
if (!post) {
return res.status(404).json({ message: 'Post not found' });
}
return res.status(200).json(post);
} catch (error) {
console.error('Error fetching post:', error);
return res.status(500).json({ message: 'Internal server error' });
}
}
API 路由缓存
为了提升性能,你可能需要对API响应进行缓存。Next.js自身不直接提供API缓存机制,但你可以借助第三方库如 swr(用于客户端缓存)或在服务器端使用Redis等缓存服务。
服务器端缓存示例(使用 Redis)
首先,安装 redis 和 ioredis:
npm install redis ioredis
然后,在API路由中使用Redis缓存数据:
import redis from 'ioredis';
const redisClient = new redis(process.env.REDIS_URL);
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const { id } = req.query;
let post;
try {
// 尝试从Redis获取缓存
post = await redisClient.get(`post:${id}`);
if (post) {
post = JSON.parse(post);
return res.status(200).json(post);
}
} catch (err) {
console.error('Redis error:', err);
}
// 缓存中没有数据,从数据库获取
post = await getPostById(id as string);
if (post) {
// 存储到Redis以便下次使用
redisClient.set(`post:${id}`, JSON.stringify(post));
res.status(200).json(post);
} else {
res.status(404).json({ message: 'Post not found' });
}
}
CORS 支持
跨源资源共享(CORS)是Web安全的重要方面,Next.js API路由默认支持CORS。你可以通过配置来进一步控制CORS策略:
import Cors from 'cors'; // 安装 cors 库
// 初始化 CORS 中间件
const cors = Cors({
methods: ['GET', 'HEAD'],
});
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
// 使用 CORS 中间件
await new Promise((resolve, reject) => {
cors(req, res, (result) => {
if (result instanceof Error) {
reject(result);
} else {
resolve(result);
}
});
});
// .
…后续处理逻辑
}
2500G计算机入门到高级架构师开发资料超级大礼包免费送!