ardatan / graphql-mesh

🕸️ GraphQL Mesh - The Graph of Everything - Federated architecture for any API service
https://the-guild.dev/graphql/mesh
MIT License
3.21k stars 331 forks source link

Inaccurate transformed document caching #7038

Open hajnalben opened 1 month ago

hajnalben commented 1 month ago

The caching part of the code for transformed documents in the legacy runtime is totally inaccurate. It doesn't prevent the call of applyRequestTransforms but instead of it overwrites its result.

Source: packages/legacy/runtime/src/useSubschema.ts

The code below is copied from the master branch ("version": "0.99.7")

const transformationContext: Record<string, any> = {};
const transformedRequest = applyRequestTransforms(
  originalRequest,
  delegationContext,
  transformationContext,
  subschema.transforms,
);
const cachedTransfomedDocumentNode: DocumentNode = transformedDocumentNodeCache.get(
  originalRequest.document,
);
if (cachedTransfomedDocumentNode) {
  transformedRequest.document = cachedTransfomedDocumentNode;
} else {
  transformedDocumentNodeCache.set(originalRequest.document, transformedRequest.document);
}

As you can see the applyRequestTransforms is called every time without checking the cache for match. After that the transformed document will be overwritten by the cache result. Also the caching logic doesn't consider transformers that produce different transformed documents based on the originalRequest.variables (example: @graphprotocol/client-auto-pagination)

ardatan commented 1 month ago

Would you create a reproduction?

hajnalben commented 1 month ago

Reproduction repository

See the race1.ts and race2.ts in the repo. Run them separately and see the difference. They are executing the same query with different variables (A -> B | B -> A). You could debug the installed "@graphql-mesh/runtime": "0.99.7" in the node_modules and see the missfunctionality of the cache I described above. Also fixed it locally and based on that I have created the PR.