如何在Next.js 13应用程序路由器中获取动态片段?

huangapple go评论82阅读模式
英文:

How to get dynamic segment in Next.js 13 app router?

问题

我想从Next.js 13使用API Router和MongoDB作为我的数据库来获取数据。目前,我正在使用新的App Router。

当我从集合中获取所有数据时,成功了,但是当我想要获取单个数据时,失败了。

错误信息如下:

TypeError: Cannot read properties of undefined (reading 'id')
    at GET (webpack-internal:///(sc_server)/./app/api/shop/[id]/route.tsx:14:30)
    // 更多错误信息...

以下是我的代码

/app/api/shop/[id]/route.tsx

import { connectToDatabase } from "@/lib/mongo";
import { NextRequest, NextResponse } from "next/server";
import { ObjectId } from "mongodb";

export async function GET(req: NextRequest, res: NextResponse) {
  try {
    const id = req.query.id;
    const client = await connectToDatabase();
    const db = client.db("MyShopDB");

    const oneProduct = await db.collection("Products").findOne({ _id: ObjectId(id) });

    if (oneProduct)
      return NextResponse.json(oneProduct);
    else
      return res.status(404).json({ message: "Products Not Found" });
  } catch (error) {
    console.log(error);
    return new Response("Failed to fetch all prompts", { status: 500 });
  }
}

以下是获取所有产品的代码

/app/api/shop/route.tsx

import { connectToDatabase } from "@/lib/mongo";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest, res: NextResponse) {
  try {
    const client = await connectToDatabase();
    const db = client.db("MyShopDB");
    
    const allProducts = await db.collection("Products").find().toArray();

    return NextResponse.json(allProducts);
  } catch (error) {
    return new Response("Failed to fetch all prompts", { status: 500 });
  }
}

希望以上翻译对你有帮助。如果有任何问题,请随时提出。

英文:

I want to fetch a data using API Router from Next.js 13 using MongoDB as my DBMS. Currently, I'm using the new App Router.

When I'm fetching all data from a collection it succeeded, but when I want to fetch only one data, it fails.

The error says

TypeError: Cannot read properties of undefined (reading 'id')
    at GET (webpack-internal:///(sc_server)/./app/api/shop/[id]/route.tsx:14:30)
    at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:265:43)
    at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:111:36)
    at NoopContextManager.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:360:30)
    at ContextAPI.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:30:58)
    at NoopTracer.startActiveSpan (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:953:34)
    at ProxyTracer.startActiveSpan (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:993:36)
    at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:100:107)
    at NoopContextManager.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:360:30)
    at ContextAPI.with (webpack-internal:///(sc_server)/./node_modules/next/dist/compiled/@opentelemetry/api/index.js:30:58)
    at NextTracerImpl.trace (webpack-internal:///(sc_server)/./node_modules/next/dist/server/lib/trace/tracer.js:100:32)
    at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:253:53)
    at AsyncLocalStorage.run (node:async_hooks:330:14)
    at Object.wrap (webpack-internal:///(sc_server)/./node_modules/next/dist/server/async-storage/static-generation-async-storage-wrapper.js:41:24)
    at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:207:97)
    at AsyncLocalStorage.run (node:async_hooks:330:14)
    at Object.wrap (webpack-internal:///(sc_server)/./node_modules/next/dist/server/async-storage/request-async-storage-wrapper.js:77:24)
    at eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:206:75)
    at AsyncLocalStorage.run (node:async_hooks:330:14)
    at AppRouteRouteModule.execute (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:203:56)
    at AppRouteRouteModule.handle (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:326:41)
    at RouteHandlerManager.handle (D:\Projects\MyShop\node_modules\next\dist\server\future\route-handler-managers\route-handler-manager.js:28:29)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async doRender (D:\Projects\MyShop\node_modules\next\dist\server\base-server.js:996:38)
    at async cacheEntry.responseCache.get.incrementalCache.incrementalCache (D:\Projects\MyShop\node_modules\next\dist\server\base-server.js:1172:40)
    at async D:\Projects\MyShop\node_modules\next\dist\server\response-cache\index.js:99:36

Here is my code

/app/api/shop/[id]/route.tsx

import { connectToDatabase } from "@/lib/mongo";
import { NextRequest, NextResponse } from "next/server";
import { ObjectId } from "mongodb";

export async function GET (req : NextRequest, res : NextResponse) {
  try {
    const id = req.query.id;
    const client = await connectToDatabase();
    const db = client.db("MyShopDB");
    // console.log(req);
  
    const oneProduct = await db.collection("Products").findOne({ _id: ObjectId(id) });
  
    // return new Response(JSON.stringify(allProducts), { status: 200 });
    if(oneProduct)
      return NextResponse.json(oneProduct)
    else 
      return res.status(404).json({message: "Products Not Found"})
  } catch (error) {
    console.log(error);
    return new Response("Failed to fetch all prompts", { status: 500 })
  }
}

Here is code for fetching all products
/app/api/shop/route.tsx

import { connectToDatabase } from "@/lib/mongo";
import { NextRequest, NextResponse } from "next/server";

export async function GET (req: NextRequest, res: NextResponse) {
  try {
    const client = await connectToDatabase();
    const db = client.db("MyShopDB");
    console.log(req);
  
    const allProducts = await db.collection("Products").find().toArray();
  
    // return new Response(JSON.stringify(allProducts), { status: 200 });
    return NextResponse.json(allProducts);
  } catch (error) {
    return new Response("Failed to fetch all prompts", { status: 500 })
  }
}

答案1

得分: 1

错误很可能是由对req.query.id的访问引起的,这在app文件夹中的动态API路由中是无效的。

当在app目录中使用具有动态段的路由处理程序时,可以从函数的第二个参数中的params属性中访问动态参数。

// `/app/api/shop/[id]/route.tsx`

import { type NextRequest } from 'next/server';

export async function GET(request: Request, { params }: { params: { id: string } }) {
    const id = params.id;
    console.log(id);
    // 其余的API函数
}

有关更多详细信息,请参阅路由处理程序,动态路由段文档。

英文:

The error is most likely caused by the access to req.query.id, which is not valid for a dynamic API route in the app folder.

When using a route handler with dynamic segments inside the app directory, the dynamic parameter can be accessed from the params property in the function's second parameter.

// `/app/api/shop/[id]/route.tsx`

import { type NextRequest } from 'next/server';

export async function GET(request: Request, { params }: { params: { id: string } }) {
    const id = params.id;
    console.log(id);
    // Rest of your API function
}

For more details see Route Handlers, Dynamic Route Segments documentation.

huangapple
  • 本文由 发表于 2023年6月29日 13:06:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76578186.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定