
在 Next.js 13 的 App Router 中,API 路由不再支持 req.query 解构,必须使用 request.nextUrl.searchParams 获取 URL 查询参数。
在 next.js 13 的 app router 中,api 路由不再支持 `req.query` 解构,必须使用 `request.nexturl.searchparams` 获取 url 查询参数。
Next.js 13 引入了全新的 App Router 架构,其 API 路由(位于 app/api/.../route.ts 或 .js)与旧版 Pages Router 完全不同:它不接收 (req, res) 参数,也不提供 req.query 对象。你当前的代码沿用了 Pages Router 的处理方式,因此在 App Router 环境下会抛出 TypeError: Cannot destructure property 'filterBy' of 'request.query' as it is undefined。
✅ 正确写法:使用 NextRequest 和 searchParams
API 路由必须导出命名函数(如 GET、POST),并接收类型为 NextRequest 的单一参数。查询参数需通过 request.nextUrl.searchParams(一个 URLSearchParams 实例)提取:
// app/api/events/route.ts
import { NextRequest, NextResponse } from 'next/server';
import Event from '@models/Event';
import { connectToMongoDB } from '@utils/database/connectToMongoDB';
export async function GET(request: NextRequest) {
// ✅ 正确获取查询参数
const searchParams = request.nextUrl.searchParams;
const filterBy = searchParams.get('filterBy'); // string | null
const status = searchParams.get('status'); // string | null
// 解构其余参数(可选)
const filters: Record<string, string> = {};
for (const [key, value] of searchParams.entries()) {
if (key !== 'filterBy') {
filters[key] = value;
}
}
try {
await connectToMongoDB();
// 示例:根据 filterBy 和 status 查询事件
const events = await Event.find(
filterBy === 'status' && status ? { status } : {}
);
return NextResponse.json({ events }, { status: 200 });
} catch (error) {
console.error('API route error:', error);
return NextResponse.json(
{ error: 'Failed to fetch events' },
{ status: 500 }
);
}
}⚠️ 注意事项
- 不要使用默认导出或 (req, res) => {}:App Router 的 API 路由仅支持具名导出(GET、POST 等),且无 res 对象;响应必须返回 NextResponse。
- searchParams.get() 返回 string | null:务必做空值判断,避免运行时错误。例如:if (!filterBy) return NextResponse.json({ error: 'Missing filterBy' }, { status: 400 });
- 路径匹配规则:/api/events?filterBy=status&status=Live 会被正确路由到 app/api/events/route.ts,无需额外配置。
- 客户端调用保持不变:你在 page.jsx 中使用的 fetch('/api/events?filterBy=status&status=Live') 完全正确,无需修改。
? 验证技巧
可在路由中快速调试:
console.log('Full search params:', Object.fromEntries(searchParams.entries()));
// 输出:{ filterBy: 'status', status: 'Live' }总之,迁移至 App Router 后,务必抛弃 Pages Router 的请求处理范式。统一使用 NextRequest + searchParams 是获取查询参数的唯一标准方式——简洁、类型安全,且与 Next.js 的中间件和重写机制深度集成。



















