On-demand revalidation for data fetching with Prisma
Unanswered
Giant panda posted this in #help-forum
Giant pandaOP
I want to setup on-demand revalidation for my data fetching. However, I am using prisma to fetch the data, which means that I cannot set cache tags (as you can with fetch requests).
I cannot do it with path revalidation either, since I have the following structure: app/[sites] - So let's say I have sites X, Y, Z. I don't want Y and Z to fetch if there's a new post for site X.
Are there any other clever hacks for setting up on-demand revalidation for data fetching?
Could I simply put my prisma fetch in an /api route handler and access it via fetch like that? Or would that result in other unforseen issues?
I cannot do it with path revalidation either, since I have the following structure: app/[sites] - So let's say I have sites X, Y, Z. I don't want Y and Z to fetch if there's a new post for site X.
Are there any other clever hacks for setting up on-demand revalidation for data fetching?
Could I simply put my prisma fetch in an /api route handler and access it via fetch like that? Or would that result in other unforseen issues?
40 Replies
@Giant panda I want to setup on-demand revalidation for my data fetching. However, I am using prisma to fetch the data, which means that I cannot set cache tags (as you can with fetch requests).
I cannot do it with path revalidation either, since I have the following structure: app/[sites] - So let's say I have sites X, Y, Z. I don't want Y and Z to fetch if there's a new post for site X.
Are there any other clever hacks for setting up on-demand revalidation for data fetching?
Could I simply put my prisma fetch in an /api route handler and access it via fetch like that? Or would that result in other unforseen issues?
relevant issue: https://github.com/vercel/next.js/issues/49387
basically for now i would use
pages directory's res.revalidaterevalidatePath is missing some critically important features like the one you describedwhile
res.revalidate works fine for your caseGiant pandaOP
Alright - Is it possible to have both app dir route handlers as well as pages/api endpoints? Or do I have to move all of my api endpoints to the pages dir?
@Giant panda Alright - Is it possible to have both app dir route handlers as well as pages/api endpoints? Or do I have to move all of my api endpoints to the pages dir?
yes the app directory and the pages directory can coexist, like the new nextjs-forum.com app has them working side-by-side https://github.com/rafaelalmeidatk/nextjs-forum/tree/main/apps/web
@joulev relevant issue: https://github.com/vercel/next.js/issues/49387
Giant pandaOP
Thanks!
@joulev yes the app directory and the pages directory can coexist, like the new nextjs-forum.com app has them working side-by-side <https://github.com/rafaelalmeidatk/nextjs-forum/tree/main/apps/web>
Giant pandaOP
Perfect - Okay, I'll resort to using a pages endpoint for that
Giant pandaOP
Getting the following error when I do
Never had this issue in the past - Using Turborepo
res.revalidate now:Package subpath './server.edge' is not defined by "exports" in /Users/ssardorf/dev/12s12m/verk/node_modules/react-dom/package.jsonNever had this issue in the past - Using Turborepo
Giant pandaOP
Now getting:
Failed to revalidate /sites/demo: Invalid response 200, which seems to be related to this issue: https://github.com/vercel/next.js/issues/43132Giant pandaOP
@joulev - The issue with the above approach is that you cannot use
Seems like the revalidation functionality implemented with the app directory was not really thought through before release
res.revalidate on a page that is in the app directory, because res.revalidate requires getStaticProps, as outlined here https://github.com/vercel/next.js/issues/48771Seems like the revalidation functionality implemented with the app directory was not really thought through before release
So either I:
a) Move all routes to the pages directory
or
b) Use a sub-optimal revalidation strategy.
What a shame 😦
a) Move all routes to the pages directory
or
b) Use a sub-optimal revalidation strategy.
What a shame 😦
Giant pandaOP
I posted on the issue: https://github.com/vercel/next.js/issues/49387#issuecomment-1586131088
@Giant panda <@484037068239142956> - The issue with the above approach is that you cannot use `res.revalidate` on a page that is in the app directory, because res.revalidate requires `getStaticProps`, as outlined here https://github.com/vercel/next.js/issues/48771
Seems like the revalidation functionality implemented with the app directory was not really thought through before release
Interesting - I’ve been using res.revalidate for my appdir pages normally and it works quite well
@joulev Interesting - I’ve been using res.revalidate for my appdir pages normally and it works quite well
Giant pandaOP
According to this comment, res.revalidate should not be possible without getStaticProps https://github.com/vercel/next.js/issues/48771#issuecomment-1539446616
@Giant panda According to this comment, res.revalidate should not be possible without getStaticProps https://github.com/vercel/next.js/issues/48771#issuecomment-1539446616
Yeah that’s why I think it’s interesting. It doesn’t work according to Kasper but it actually works (?) when I use it in prod
Agree yeah appdir’s revalidation mechanism is not good enough
Giant pandaOP
I'm getting this -
So perhaps it's working, but throwing an error?
Failed to revalidate /sites/demo: Invalid response 200 So perhaps it's working, but throwing an error?
@Giant panda I'm getting this - `Failed to revalidate /sites/demo: Invalid response 200`
So perhaps it's working, but throwing an error?
In dev mode it doesn’t work, but in prod mode it does - try it
Well, that’s just a workaround for now until revalidatePath() works well
#49387 is really an important ticket and hopefully they resolve that soon
@joulev In dev mode it doesn’t work, but in prod mode it does - try it
Giant pandaOP
Gonna test on prod to see if res.revalidate is gonna work
Does appdir have time-interval revalidation disabled by default?
Does appdir have time-interval revalidation disabled by default?
Actually i think it only stopped working in dev mode recently
I used to use it in production extensively before moving to revalidatePath (which now works fine for my particular use case, but as you demonstrated doesn’t work fine for all use cases where we need it)
@joulev Actually i think it only stopped working in dev mode recently
Giant pandaOP
Also getting the error in prod
@joulev it works fine here
Giant pandaOP
That's very weird. Where are you calling api/revalidate from? And why is it running seemingly when you start the server?
@Giant panda That's very weird. Where are you calling api/revalidate from? And why is it running seemingly when you start the server?
i start the server, then send a request to
/api/revalidateGiant pandaOP
I see
Giant pandaOP
Wondering if there is any possibility of adding tag as a const in the page functions. So instead of cache tags only working in fetch requests, it could work for any type of data fetching (E.g. using Prisma)
Example if we have
That way, we could invalidate whichever data fetching strategy is being used (be it
Example if we have
app/[id]/page.tsxexport default async function Post(params:{id:string}){
const TAG = params.id
const post = await prisma.post.findUnique({
where: {
id: params.id
}
}That way, we could invalidate whichever data fetching strategy is being used (be it
fetch or directly from database or whichever)@joulev i start the server, then send a request to `/api/revalidate`
Giant pandaOP
seems like res.revalidate will work if you don't have custom middleware https://github.com/vercel/next.js/issues/50464 - Even though the docs mention that
middleware won't be executed for On-Demand ISR requestsGiant pandaOP
Okay - Seems like we can use
Then you can invalidate the post by invalidating the postId as a tag like so:
unstable_cache to achieve the same functionality as fetch tag invalidation, but for any type of data fetching.import { unstable_cache } from 'next/cache'
export default async function post({
postId
}: {
postId:string
}) {
const posts = await unstable_cache(
async () => {
return prisma.post.findUnique({
where: {
postId: postId,
}
})
},
[postId],
{ tags: [postId] }
)()Then you can invalidate the post by invalidating the postId as a tag like so:
revalidateTag(postId)@joulev Where did you find this
Giant pandaOP
In the depths of the next source code
And then Steven Tey replied to one of my tweets with it as well
nice, so at least we know they are working on something
praying for a new minor version to be released
it's about time as well, should land within this month
