Add a Query parameter to each backed call using apolloclient and useQuery hook

Trying to add a new traceId as query parameter to uri in apolloClient.


const queryParameter = "?traceId=" + uuid() 
function getClient() {
  
  const client : any = new ApolloClient({
  uri: getAPIEndpoint()?.concat(queryParameter) ,
  cache: new InMemoryCache(),
  credentials: 'include'
});
return client
}

ReactDOM.render(
  <React.StrictMode>
    <ErrorBoundary>
      <ThemeProvider theme={mdTheme}>
        <ApolloProvider client={getClient()}>
          <Provider store={store}>
            <Router>
              <App />
            </Router>
          </Provider>
        </ApolloProvider>
      </ThemeProvider>
    </ErrorBoundary>
  </React.StrictMode>,
  document.getElementById('root')
);

when useQuery or useLazy Query hook is called we want apolloClient to add a new traceId to each graphql backend call. But we see that same traceId is passed in graphql calls

how to add a traceId or key-value as query parameter to apollo client

That is because your

const queryParameter = "?traceId=" + uuid();

line only executes once, and you also only create your ApolloClient instance only once. You are in the wrong place to do this here.

Something like this would happen in a Link:

const traceIdLink = setContext(() => {
  const queryParameter = "?traceId=" + uuid();
  return {
    uri: getAPIEndpoint()?.concat(queryParameter),
  };
});

And then you’d add that link:

new ApolloClient({
  cache: new InMemoryCache(),
  credentials: "include",
  link: from([traceIdLink, new HttpLink({ uri: getAPIEndpoint() })]),
});

Another variant for this is shown here in the docs

Thanks for your response Lenz
i tried your suggestions and I still see same traceId value for all my Graphql calls. These calls are made from child component using hooks useQuery, useLazyQuery. Is there a way to pass link or queryParameter with useQuery and useLazyQuery

  const { loading, error, data } = useQuery(GetControlsMetaDataDashboard());
useEffect(() => {
    if (!loading) {
      const result = data?.ControlsMetaData;

      if (result && result.length > 0) {
        if (mock) {
          const mockData = [
            ...result,
            mock,
          ]
          setMetaData(mockData);
        } 
      }
    }},[loading, error, data] )

Generally, that link should create a new uuid on every new request, it doesn’t matter how you make your query.

Have you also tried the other variant that I have linked to?

yes , I have tried setContext with and without setTimeout wrapped around a promise. traceId remains the same for all the graphQl calls
One other option is adding a second parameter “client” to useLazyQuery which contains a new apolloClient object with a traceId(as shown below). When the backend call is made apolloclient still has the old traceId and is not appended with new one

type or paste c const traceIdLink = setContext(
    request =>
      new Promise((success, fail) => {
        const queryParameter = "?traceId=" + uuid();
        // do some async lookup here
        setTimeout(() => {
          success({ uri: getAPIEndpoint()?.concat(queryParameter) });
        }, 10);
      })
  );

  const client : any = new ApolloClient({
    link: from([traceIdLink, new HttpLink({ uri: getAPIEndpoint() })]),
    cache: new InMemoryCache(),
    credentials: 'include'
  });
  
  const [fetchEncryptionAtRestAgg, { loading, error, data }] = useLazyQuery(apiCallMethodsControl[metaData.title](), client);ode here

The other solution I linked to doesn’t have anything to do with setContext at all, I think you might have missed that:

const customFetch = (uri, options) => {
  return fetch(`${getAPIEndpoint()}?traceId=${uuid()}`, options);
};

const link = new HttpLink({ fetch: customFetch });