Can ApolloClient (Web client JS) automatically add the x-apollo-operation-* headers to outgoing requests?

Hi, Apollo newbie here. I am working on implementing an extension to the library I maintain to detect operation name and id from outgoing Apollo requests, by observing the headers x-apollo-operation-id and x-apollo-operation-name, which I had thought to be a standard on outgoing requests. While implementing a test build with the apolloclient NPM package, I am noticing that none of the requests I send are getting those headers appended. Is it reasonable to expect most Apollo implementations to have these headers present? What am I doing wrong in that they are not being appended to my requests in my testing application?

TYIA

At this point, the web clients don’t add those.

You can add a custom link that would add them - see this code snippet for a headersLink you can add to your link chain:

import { type DocumentNode, print } from "graphql";
import { setContext } from "@apollo/client/link/context";
import { getOperationDefinition } from "@apollo/client/utilities";


const operationHashes = new WeakMap<DocumentNode, string | Promise<string>>();
const headersLink = setContext(async (operation, prevContext) => {
  if (!operationHashes.has(operation.query)) { 
    operationHashes.set(operation.query, new Promise<string>((resolve) => {
      const hash = sha256(print(operation.query));
      operationHashes.set(operation.query, hash);
      resolve(hash);
    }));
  }
  const operationId = operationHashes.get(operation.query)!;

  return {
    ...prevContext,
    headers: {
      ...prevContext.headers,
      "x-apollo-operation-id": await operationId,
      "x-apollo-operation-name": operation.operationName,
      "x-apollo-operation-type": getOperationDefinition(operation.query),
    },
  };
});


// from https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
async function sha256(message: string) {
  const msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array
  const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8); // hash the message
  const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
  const hashHex = hashArray
    .map((b) => b.toString(16).padStart(2, "0"))
    .join(""); // convert bytes to hex string
  return hashHex;
}
1 Like