Next.js 13的API路由在使用cache:no-store时仍然保持静态。

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

Nextjs 13 Api Route remains static when calling with cache:no-store

问题

我正在使用Next.js 13、React和Firestore构建一个Web应用程序。我创建了一个用于从Firestore获取数据的API路由,不使用缓存(SSR)。在开发模式下一切正常,但当我构建项目时,Next.js将我的API路由呈现为静态的,因此我收到旧数据。是否有方法创建一个SSR API路由?

这是我在Dashboard页面中的GET请求:

const getExamDate = async () => {
  const response = await fetch("http://localhost:3000/api/ExamInfo", {
    cache: "no-store",
  });
  const data = await response.json();
  if (data) {
    console.log("fetched again");
  }
  return data;
};

这是我创建的访问Firestore数据的API端点:

export async function GET() {
  try {
    const Exams = [];
    const documentInfo = await getDocs(collection(db, "Exams"));
    documentInfo.forEach((doc) => {
      Exams.push(doc.data());
    });
    console.log("API: ", Exams);
    return NextResponse.json({ Exams, status: 200 });
  } catch (error) {
    console.error(error);
    return NextResponse.json(
      { error: "Failed to fetch exam data" },
      { status: 401 }
    );
  }
}

构建时的结果如下:

○ /  
├ ○ /api/ExamInfo (static)  
├ λ /Dashboard (SSR)

因此,对于我的Dashboard,一切正常,它是服务器端渲染的,但我的API端点仍然是静态的,这导致获取旧数据(构建时的数据)。如何配置我的端点也为SSR,以便每个请求都获得当前数据?

更新: 有一个解决方法可以强制端点在每个请求中获取数据:

通过将请求参数传递给GET函数,并记录每个端点调用的请求,可以实现这一点,从而使API路由在每个请求中都会被调用:

export async function GET(request) { //将请求作为参数传递
  console.log(request.url); //记录URL
  try {
    const Exams = [];
    const documentInfo = await getDocs(collection(db, "Exams"));
    documentInfo.forEach((doc) => {
      Exams.push(doc.data());
    });
    console.log("API: ", Exams);
    return NextResponse.json({ Exams, status: 200 });
  } catch (error) {
    console.error(error);
    return NextResponse.json(
      { error: "Failed to fetch exam data" },
      { status: 401 }
    );
  }
}

但在我看来,这不是正确的做法,所以有没有人知道在服务器端每个请求上获取数据的“正确方法”?

英文:

I am building a web-application with nextjs.13, react and firestore. I created a api route for fetching data from firestore with no-cache (SSR). In development mode everything works fine, but when i build the project, nextjs renders my api route static, so i receive old data. Is there a way around how to create a SSR Api route?

This is my GET-Request in my Dashboard page.jsx:

const getExamDate = async () => {
  const response = await fetch("http://localhost:3000/api/ExamInfo", {
    cache: "no-store",
  });
  const data = await response.json();
  if (data) {
    console.log("fetched again");
  }
  return data;
};

This is my created API-Endpoint which accesses the Firestore Data:

export async function GET() {
  try {
    const Exams = [];
    const documentInfo = await getDocs(collection(db, "Exams"));
    documentInfo.forEach((doc) => {
      Exams.push(doc.data());
    });
    console.log("API: ", Exams);
    return NextResponse.json({ Exams, status: 200 });
  } catch (error) {
    console.error(error);
    return NextResponse.json(
      { error: "Failed to fetch exam data" },
      { status: 401 }
    );
  }
}

And this is the result when building:

○ /  
├ ○ /api/ExamInfo (static)  
├ λ /Dashboard (SSR)

So for my Dashboard everything works fine and its server side rendered, but my api endpoint remains static, which results in getting old data (Buildtime data).
How do i configure my Endpoint also SSR, so i get the current data for each request?

UPDATE: There is a workaround to force the Endpoint to fetch for every request:
By adding the request parameter, and logging it for each endpoint call, the API-Route is called for every request:

export async function GET(request) { //passing the request as parameter
  console.log(request.url); //Logging the URL
  try {
    const Exams = [];
    const documentInfo = await getDocs(collection(db, "Exams"));
    documentInfo.forEach((doc) => {
      Exams.push(doc.data());
    });
    console.log("API: ", Exams);
    return NextResponse.json({ Exams, status: 200 });
  } catch (error) {
    console.error(error);
    return NextResponse.json(
      { error: "Failed to fetch exam data" },
      { status: 401 }
    );
  }
}

But in my opinion this isn't the right way to do, so does anyone know the "right way" of fetching the data from the endpoint for each request on server side?

答案1

得分: 3

如果您想实现更清晰的解决方案,可以将export const dynamic = 'force-dynamic'添加到您的API路由中。根据文档,"此选项等效于:

  • 在页面目录中使用getServerSideProps()。
  • 在布局或页面中将每个fetch()请求的选项设置为{ cache: 'no-store', next: { revalidate: 0 } }。
  • 将段配置设置为export const fetchCache = 'force-no-store'"。
英文:

If you want to implement a cleaner solution then you can instead add export const dynamic = 'force-dynamic' to your API route.

According to the documentation, "this option is equivalent to:

  • getServerSideProps() in the pages directory.

  • Setting the option of every fetch() request in a layout or page to { cache: 'no-store', next: { revalidate: 0 } }.

  • Setting the segment config to export const fetchCache = 'force-no-store'"

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

发表评论

匿名网友

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

确定