Server side query retry and caching with request scoped QueryClient #2596
+373
−247
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What are the relevant tickets?
Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it. [function] ^^^^^^^^
https://mit-office-of-digital-learning.sentry.io/issues/6770939422/?environment=production&project=4506260054540288&query=is%3Aunresolved%20function&referrer=issue-streamDescription (What does it do?)
queryClient.fetchQuery()
and enforced with ESLint rules.safeGenerateMetadata
utility that catches errors. Uncaught errors here were responsible for the error page being shown as a result of the non-serializable error being passed to client components.The approach is to reuse the QueryClient for all API requests made from the server (page server components,
generateMetadata
, client components during the SSR render phase). The QueryClient contains our retry logic, so we able to specify it in one place. React's server component cacheReusing a QueryClient instance and therefore its QueryCache enables us, to share a single instance across a request lifecycle using React cache. This provides a cache layer that prevents duplicate API requests made during SSR prefetching and metadata generation. The instance is memoized and invalidated for each server request.
How can this be tested?
Request caching
COMPOSE_PROFILES=backend,apisix,keycloak docker compose up
(or use local proxy described below).cd frontends/main && yarn build
PORT=8062 yarn start
docker compose logs -f apigateway
Retry mechanism
yarn && yarn proxy:watch
.Additional Context
I also looked at using native fetch on the Axios instance - it can be set as the adapter on the config. The goal is that we make use of Next.js' data cache and route segment config for caching rules, however the fetch adapter is not compatible with React Query - the retry mechanism is called, but no actual requests are made; nor is it compatible with Next.js - requests are persisted (in ./main/.next/cache/fetch-cache), however config is ignored and all requests have a max-age of 1 year, which is not what we want.