Open aaronLejeune opened 2 months ago
So, what you likely need is the useDataCache
composable. If you want to cache most of your GraphQL queries, then it probably makes sense to create your own composable that acts as a wrapper around useDataCache
, useAsyncData
and useQuery
.
However, I'm not entirely familiar with @nuxtjs/apollo
because I maintain my own Nuxt GraphQL client. As you mentioned, Apollo has a client cache; I'm not sure if this exclusively only applies to client side or if it would be possible to provide your own "cache provider" so to say? If yes, then you could actually "hook" into this part of Apollo and use useDataCache
there to get and set responses into cache. That way you could easily continue to use the default composables and the caching would happen "automatically" in the background, basically.
But assuming this is not easily possible, then a custom composable is the way to go. However, it can get tricky to get the types right, together with useAsyncData
and the GraphQL types. I quickly looked at the implementations of useQuery and useAsyncQuery, however not all of the types seem to be properly exported (but I did not check 100%). So this is what a custom composable might look like, as a very rough, non-working starting point:
import { useAsyncData, type AsyncData } from '#app'
import { hash } from 'ohash'
export function useCachedQuery<TResult, TVariables extends OperationVariables>(
document: DocumentParameter<TResult, TVariables>,
variables?: VariablesParameter<TVariables>,
): AsyncData<TResult, unknown> {
// Create a unique key.
const key = hash(document, variables)
return useAsyncData(key, async function (app) {
// Try to get from cache.
const { value, addToCache } = await useDataCache<TResult>(
key,
app?.ssrContext?.event,
)
// If we have a value from cache, return it.
if (value) {
return value
}
// Make the GraphQL query.
const result = await useQueryImpl(document, variables)
// Add to cache.
await addToCache(result)
// Return the value.
return result
})
}
If you also want to implement the options of useAsyncData
(such as transform
or getCachedData
), then it gets even more trickier. I have done something similar with the useCachedAsyncData composable that is provided by this module. Maybe this could also be a good starting point for you.
Hello,
TLDR; how can I enable SSR caching with Apollo combined with NuxtHub?
First of all, I want to say that I’m relatively new to caching and I’m currently trying to optimize the performance of my website. I’m using Strapi as a headless CMS and fetching content via @nuxtjs/apollo. The project is a webshop that operates in multiple languages and regions, which means a lot of dynamic content and API calls. I noticed the initial response time was realllllyyy slow, so I thought of caching some data on the server frontend as well..
I’ve started testing out NuxtHub, which looks like a great solution for easily storing cache and KV. However, I’m having trouble understanding how to properly cache the API data on the server side. The client-side caching, handled by Apollo itself, is working nicely as expected, but I want to extend caching to the server to improve performance even further.
This is a simplified version of what my current
[...slug].vue
looks like:I’ve done quite a bit of research, but I think I’m stuck and could really use some guidance. Any help or pointers would be greatly appreciated!
Thanks a lot in advance!