upleveled / graphql-example-spring-2023-atvie

https://graphql-example-spring-2023-austria-vienna.vercel.app
1 stars 0 forks source link

Nextjs cache persists while graphql query return result changed #2

Open Davidihl opened 1 year ago

Davidihl commented 1 year ago

As posted on Slack, I encountered a caching problem with graphql and nextjs.

What happened: I noticed that the result of a query does not change although the data changed. At that moment I experienced this behaviour on only one page. https://github.com/Davidihl/tierlist/blob/main/app/players/page.tsx

My guess of what the problem is: After some research, with confidence, I am blaming nextjs cache for it

-  ┌ GET /players 200 in 63ms
   │
   └──── POST http://localhost:3000/api/graphql 200 in 1ms (cache: HIT)

Also, when I run the query in Apollo Explorer, I get the expected result.

What I tried to solve it: I read through the docs but found no examples of how to force the cache to clear or to bypass it in the context of the way @prince-hub demonstrated it in the lecture (see: https://github.com/apollographql/apollo-client-nextjs)

I checked the repo we got provided from a previous cohort, but she did not used the experimental-integration but a "workaround" that I funnily enough traced back to this issue https://github.com/apollographql/apollo-client/issues/10344#issuecomment-1439992233. In this issue the experimental is proposed as solution.

I read the introduction blogpost https://www.apollographql.com/blog/announcement/frontend/using-apollo-client-with-next-js-13-releasing-an-official-library-to-support-the-app-router/ and noticed some differences to the way we queried the data in the lecture: https://github.com/upleveled/graphql-example-spring-2023-austria-vienna/blob/main/app/animals/page.tsx e.g.: not using client components that use the useQuery hook not using force-dynamic

This quote caught my eye:

Finally we are using export const dynamic = "force-dynamic"; to tell Next.js not to cache this page, so we don’t get stale data when reloading.

So I added it to my page and et voila, it works. So this feels very familiar to the database issue we had during the e-commerce project https://github.com/vercel/next.js/discussions/50695

Which leaves the question: Is there a workaround like we did for database queries?

karlhorky commented 1 year ago

The Next.js Example calls headers() internally in the database sql() function:

  // Workaround to force Next.js Dynamic Rendering:
  //
  // Wrap sql`` tagged template function to call `headers()` from
  // next/headers before each database query. `headers()` is a
  // Next.js Dynamic Function, which causes the page to use
  // Dynamic Rendering.
  //
  // https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic-rendering
  //
  // Ideally there would something built into Next.js for this,
  // which has been requested here:
  //
  // https://github.com/vercel/next.js/discussions/50695
  return ((
    ...sqlParameters: Parameters<typeof globalThis.postgresSqlClient>
  ) => {
    headers();
    return globalThis.postgresSqlClient(...sqlParameters);
  }) as typeof globalThis.postgresSqlClient;

@Eprince-hub can you think through whether it makes sense to also add some kind of workaround for Apollo Client so that things are not cached?

victor commented 1 year ago

sorry @Davidihl, that wasn't me

Davidihl commented 1 year ago

Sorry wrong mention 😅