Mixed up data on concurrent requests to vue3 SSR app with apollo client

349 Views Asked by At

I'm trying to convert a vue3 SPA that uses an apollo client to SSR with the help of vite-plugin-ssr. I'm facing an issue of mixed-up data on concurrent requests to the express server. The apollo client instance used to be global in the SPA, so I'm trying to create and use a new instance on every request.

I had this file that included the creation of the client, and wrapper functions around the client functions :

// apollo.ts - SPA

const apolloClient = new ApolloClient({
    ...
})


export const apolloQuery = async (args) => {
    // some logic

    const response = await apolloClient.query({...})

    // some logic

    return response
}

...

Those functions are used in components and store.

The integration example of apollo in vite-plugin-ssr repo uses @vue/apollo-composable

So I tried :

// app.ts

import { DefaultApolloClient } from "@vue/apollo-composable";
import { createApolloClient } from "./path/to/apollo.ts";

const createApp = () => {
   const apolloClient = createApolloClient({...})

   const app = createSSRApp({
       setup() {
          provide(DefaultApolloClient, apolloClient)
       },
       render() {
          return h(App, pageProps || {});
       }
   });
}

// apollo.ts - SSR 
import { useApolloClient } from "@vue/apollo-composable"

export const createApolloClient = (args) => {
    // some logic

    return new ApolloClient({...})
}


export const apolloQuery = async (args) => {
    // some logic

    const { client } = useApolloClient()
    const response = await client.query({...})

    // some logic

    return response
}

However, this does not work as intended because useApolloClient depends on providing the apollo instance to the app (1), or using the provideApolloClient function (2) :

  • (1) this means that calls can only be made during component setup or life cycle hooks, as it leverages the Vue core function getCurrentInstance to inject the client. So I can neither use them in the onBeforeRender that vite-plugin-ssr provides, nor in Vue onServerPrefetch hook, nor in the async call to store action.
  • (2) provideApolloClient sets the client to a global variable, and the same problem occurs on concurrent requests.

Am I at a dead end and a complete refactor of the apollo client use is needed, or am I missing something?

0

There are 0 best solutions below