I am trying to use the api route to call database and use the data to display the table. When it is in localhost, everything works. However, after I deployed it on Vercel, the data didn't update, it always display the data at deployment time(it use the cache data even I set cache to no-store
?), that's mean the data didn't request to the database every time the page is loaded.
import { EventsSchema, columns } from "./components/columns";
import { DataTable } from "@/app/match/components/data-table";
async function getData(): Promise<EventsSchema[]> {
const data = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/event`, {cache: "no-store",
}).then((res) => res.json());
return data;
}
export default async function Match() {
const data = await getData();
return (
<>
<DataTable data={data} columns={columns} />
</>
);
}
/api/event:
import { connectToDB } from "@/app/utils/database";
import Events from "@/models/events";
export const GET = async () => {
try {
await connectToDB();
const events = await Events.find({}).select(
"-_id -id -expireAt -homeNmae -awayName -competition"
)
return new Response(JSON.stringify(events), { status: 200 });
} catch (error) {
return new Response("Failed to fetch all events", { status: 500 });
}
};
I have also tried revalidatePath, however, the data is still not updating.
import { NextRequest, NextResponse } from "next/server";
import { revalidatePath } from "next/cache";
export async function GET(request: NextRequest) {
const path = request.nextUrl.searchParams.get("/match") || "/";
revalidatePath(path);
return NextResponse.json({ revalidated: true, now: Date.now() });
}
May I ask why and how can I let the page request to the database every time the client load the page(will it be too demanding for the database and the application if the number of client is large, if yes, how can I load the balance?)?
That's because in the app
directory and on production, Next.js by default, caches all fetched data in API Routes and Server Components.
With your cache: "no-store"
, if you were calling an external API, you would be ok. However, you seem to call your internal API where the same logic applies, which you can control using Route Segment Config since you seem to use an ORM:
export const dynamic = 'force-dynamic';
import { connectToDB } from "@/app/utils/database";
import Events from "@/models/events";
export const GET = async () => {
try {
await connectToDB();
const events = await Events.find({}).select(
"-_id -id -expireAt -homeNmae -awayName -competition"
)
return new Response(JSON.stringify(events), { status: 200 });
} catch (error) {
return new Response("Failed to fetch all events", { status: 500 });
}
};
Side note: calling an internal API from a server component might not be a good idea. Check out this thread.