Next.js嵌套动态API目录配置咨询:能否实现指定GET请求路由?
问题分析与解决方案
你的目录结构不符合Next.js API路由的规则,导致无法命中目标请求。在Next.js中,API路由的层级由目录结构决定,路由处理文件(Pages Router的.js/.ts,App Router的route.js/route.ts)是路由的终结点,不能在路由文件下方嵌套子目录。
正确的目录结构
根据你需要的请求路径,分两种路由系统给出正确结构:
1. Pages Router(基于pages/api目录)
pages/api └── book └── [bookId] ├── index.js # 处理 GET /api/book/1 └── content └── [contentId].js # 处理 GET /api/book/1/content/4
2. App Router(基于app/api目录)
app/api └── book └── [bookId] ├── route.js # 处理 GET /api/book/1 └── content └── [contentId] └── route.js # 处理 GET /api/book/1/content/4
代码实现示例
Pages Router 示例
处理 /api/book/[bookId]
// pages/api/book/[bookId]/index.js import fs from 'fs'; import path from 'path'; export default function handler(req, res) { const { bookId } = req.query; // 读取本地JSON文件(假设文件存放在项目根目录的data文件夹下) const filePath = path.join(process.cwd(), 'data', 'books.json'); const booksData = JSON.parse(fs.readFileSync(filePath, 'utf8')); const targetBook = booksData.find(book => book.id === parseInt(bookId)); if (targetBook) { res.status(200).json(targetBook); } else { res.status(404).json({ message: '指定书籍不存在' }); } }
处理 /api/book/[bookId]/content/[contentId]
// pages/api/book/[bookId]/content/[contentId].js import fs from 'fs'; import path from 'path'; export default function handler(req, res) { const { bookId, contentId } = req.query; const filePath = path.join(process.cwd(), 'data', 'book-contents.json'); const contentsData = JSON.parse(fs.readFileSync(filePath, 'utf8')); const targetContent = contentsData.find(content => content.bookId === parseInt(bookId) && content.id === parseInt(contentId) ); if (targetContent) { res.status(200).json(targetContent); } else { res.status(404).json({ message: '指定内容不存在' }); } }
App Router 示例
处理 /api/book/[bookId]
// app/api/book/[bookId]/route.js import fs from 'fs'; import path from 'path'; import { NextResponse } from 'next/server'; export async function GET(request, { params }) { const { bookId } = params; const filePath = path.join(process.cwd(), 'data', 'books.json'); const booksData = JSON.parse(fs.readFileSync(filePath, 'utf8')); const targetBook = booksData.find(book => book.id === parseInt(bookId)); if (targetBook) { return NextResponse.json(targetBook); } else { return NextResponse.json({ message: '指定书籍不存在' }, { status: 404 }); } }
处理 /api/book/[bookId]/content/[contentId]
// app/api/book/[bookId]/content/[contentId]/route.js import fs from 'fs'; import path from 'path'; import { NextResponse } from 'next/server'; export async function GET(request, { params }) { const { bookId, contentId } = params; const filePath = path.join(process.cwd(), 'data', 'book-contents.json'); const contentsData = JSON.parse(fs.readFileSync(filePath, 'utf8')); const targetContent = contentsData.find(content => content.bookId === parseInt(bookId) && content.id === parseInt(contentId) ); if (targetContent) { return NextResponse.json(targetContent); } else { return NextResponse.json({ message: '指定内容不存在' }, { status: 404 }); } }
关键说明
- 动态路由参数需要以目录形式定义(如
[bookId]目录),而非文件形式,这样才能嵌套子路由。 - 确保本地JSON文件的路径正确,
process.cwd()会返回项目根目录,根据你的实际文件位置调整路径。 - 调整结构后,重启Next.js开发服务器,即可正常发起
GET /api/book/1和GET /api/book/1/content/4请求。
内容的提问来源于stack exchange,提问作者Diego Massarini
相关产品推荐
相关产品推荐

