You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 11:26:12