Skip to content

add cacheTag directive#3274

Merged
duckki merged 13 commits intonextfrom
bnjjj/add_cache_key
Jul 10, 2025
Merged

add cacheTag directive#3274
duckki merged 13 commits intonextfrom
bnjjj/add_cache_key

Conversation

@bnjjj
Copy link
Contributor

@bnjjj bnjjj commented Jun 11, 2025

Add support of @cacheTag directive.

directive @cacheTag(format: String) repeatable on FIELD_DEFINITION | OBJECT

@changeset-bot
Copy link

changeset-bot bot commented Jun 11, 2025

⚠️ No Changeset found

Latest commit: fc24723

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jun 11, 2025

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

@apollo-librarian
Copy link

apollo-librarian bot commented Jun 23, 2025

⚠️ Docs preview not attached to branch

The preview was not built because the PR's base branch next is not in the list of sources.

An Apollo team member can comment one of the following commands to dictate which branch to attach the preview to:

  • !docs set-base-branch version-0.x
  • !docs set-base-branch main

Build ID: bb5d0d29bad6fc00d8fa4a8a

@bnjjj bnjjj marked this pull request as ready for review June 23, 2025 12:30
@bnjjj bnjjj requested a review from a team as a code owner June 23, 2025 12:30
@bnjjj bnjjj requested a review from duckki June 23, 2025 12:30
@bnjjj bnjjj changed the title add cacheKey specs add cacheTag specs Jun 23, 2025
Copy link
Member

@dariuszkuc dariuszkuc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add directive validations to FederationBlueprint#onValidation (link).

We should check whether tag value is provided (i.e. non-null string) and also whether it is a valid selection (for dynamic values).

Copy link
Contributor

@duckki duckki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the best way to add @cacheTag was

  • to make it a federation directive (no new link spec), but we need to bump up the federation version.
  • to use @join__directive in supergraph (this was already the case).
  • But, this combination was not a paved path. So, I implemented some paving for it.

I also added some subgraph validation tests (as a placeholder).
Sorry for pushing my commit without a prior discussion.

Copy link
Contributor

@duckki duckki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, shall we rename cachekey.test.ts to cachetag.test.ts?

@duckki duckki requested a review from dariuszkuc June 24, 2025 18:55
@duckki
Copy link
Contributor

duckki commented Jun 24, 2025

I'm ok with deferring validation to a separate PR (& Jira ticket) so that the router implementation can be unblocked.
In fact, we might need to make more design decisions on validation. For example, if cache tag is used on an interface and also used on its implementer type, should that be allowed?

@duckki duckki changed the title add cacheTag specs add cacheTag directive Jun 24, 2025
@dariuszkuc
Copy link
Member

BTW this PR should be targeting the next branch (fed v2.12)

@duckki duckki changed the base branch from main to next June 24, 2025 23:14
@duckki duckki requested a review from a team as a code owner June 24, 2025 23:14
bnjjj and others added 3 commits June 24, 2025 16:24
Signed-off-by: Benjamin <5719034+bnjjj@users.noreply.github.com>
Signed-off-by: Benjamin <5719034+bnjjj@users.noreply.github.com>
- bumped up the federation version to 2.12
- added some subgraph validation tests
- paved a path to merge any federation directives using `@join__directive` in supergraph
@duckki duckki force-pushed the bnjjj/add_cache_key branch from 2319ce2 to 1959454 Compare June 24, 2025 23:27
Copy link
Contributor

@duckki duckki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rebased on next.

Signed-off-by: Benjamin <5719034+bnjjj@users.noreply.github.com>
@bnjjj
Copy link
Contributor Author

bnjjj commented Jun 26, 2025

Thanks a lot @duckki that's awesome ! I renamed the test file to cachetag instead of cachekey. What's missing now ? What are the next steps I could do to land this first PR ?

@duckki
Copy link
Contributor

duckki commented Jun 27, 2025

BTW, we may not be able to merge into next just yet. I'm afraid there might be next releases between now and summit.

Copy link
Contributor

@sachindshinde sachindshinde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two things here:

  1. There's no way to easily determine whether a supergraph schema is using cacheTag (you have to parse all @join__directive calls to know). This means gateway won't know it should reject such supergraph schemas, as it currently relies on checking for specs it knows (similar story if router wanted to check for entitlements/rate limits). The simplest way to fix this is to add a cacheTag spec to the supergraph schema. It doesn't necessarily need any directives in it, and can be just a marker spec; that's currently what the connect spec means in supergraph schemas, IIRC.
  2. The pre-PR/existing implementation for addJoinDirectiveDirectives() has several things wrong with it. That may have been fine for connectors, but if we're going to use @join__directive more generally, we should fix the issues.
    • It currently relies on schemaToImportNameToFeatureUrl, which is computed by computeMapFromImportNameToIdentityUrl(). This function doesn't account for default-named directives, e.g. @federation__cacheTag, only imported ones. It should really be using Schema.coreFeatures, specifically the CoreFeatures.sourceFeature() function, which already accounts for this.
    • It checks directive.name directly against link, but it should really be checking against what the link's name in the subgraph schema is.
    • It's re-parsing each @link's information, when it should really just use Schema.coreFeatures.
    • For some reason, the code thinks it's possible directive.name can start with @ (the line with directive.name.startsWith('@')), but it can't, and that part should be simplified.

@duckki
Copy link
Contributor

duckki commented Jun 30, 2025

Two things here:

  1. There's no way to easily determine whether a supergraph schema is using cacheTag (you have to parse all @join__directive calls to know). This means gateway won't know it should reject such supergraph schemas, as it currently relies on checking for specs it knows (similar story if router wanted to check for entitlements/rate limits). The simplest way to fix this is to add a cacheTag spec to the supergraph schema. It doesn't necessarily need any directives in it, and can be just a marker spec; that's currently what the connect spec means in supergraph schemas, IIRC.

I'd like to avoid adding a new supergraph spec link, since we have too many already. I wish there was a way to indicate the composition version in supergraph beyond the join spec version. Or, we could increment the join spec version just to indicate the federation version is 2.12+.

Having said that, in practice, older Router versions will fail to resolve @cacheTag after extracting subgraphs. Yes, it will be better to error at an earlier stage, but it's not disastrous. I'm not 100% sure if Gateway will fail or not. JS composition (via composer-tool) didn't fail. So, there is a concern.

  1. The pre-PR/existing implementation for addJoinDirectiveDirectives() has several things wrong with it. That may have been fine for connectors, but if we're going to use @join__directive more generally, we should fix the issues.

    • It currently relies on schemaToImportNameToFeatureUrl, which is computed by computeMapFromImportNameToIdentityUrl(). This function doesn't account for default-named directives, e.g. @federation__cacheTag, only imported ones. It should really be using Schema.coreFeatures, specifically the CoreFeatures.sourceFeature() function, which already accounts for this.
    • It checks directive.name directly against link, but it should really be checking against what the link's name in the subgraph schema is.
    • It's re-parsing each @link's information, when it should really just use Schema.coreFeatures.
    • For some reason, the code thinks it's possible directive.name can start with @ (the line with directive.name.startsWith('@')), but it can't, and that part should be simplified.

100% agreed. I'll address that.

- to indicate the supergraph uses `@federation__cacheTag` directive (wrapped in `@join__directive`).
- The @cacheTag itself is not directly used in supergraphs.
- added `useJoinDirective` option for directive specifications, so spec link can be added in supergraph while
  directives are composed using `@join__directive`.
- fixed feature url computation logic in `addJoinDirectiveDirectives` to use `Schema.coreFeatures`.
- fixed link identity check logic in `addJoinDirectiveDirectives`.
@duckki duckki force-pushed the bnjjj/add_cache_key branch from 8b9e769 to 461967c Compare July 2, 2025 04:22
… directive.

- added cacheTag spec to the router supported spec list.
@duckki duckki requested a review from dariuszkuc July 3, 2025 00:42
Copy link
Contributor

@sachindshinde sachindshinde left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some minor things to fix below, but after that it should be good to go!

args = [],
composes = false,
supergraphSpecification = undefined,
useJoinDirective = undefined,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a boolean, you'll want

Suggested change
useJoinDirective = undefined,
useJoinDirective = false,

here instead.

Copy link
Contributor

@duckki duckki Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed the DirectiveCompositionSpecification type definition to be non-nullable bool, so it's simpler/clearer.
But, I'd like to keep the useJoinDirective parameter optional for this function, while the default value was changed to false. Otherwise, all call sites need to be updated.

@duckki duckki force-pushed the bnjjj/add_cache_key branch from 8c571e1 to fc24723 Compare July 10, 2025 01:33
@duckki duckki dismissed dariuszkuc’s stale review July 10, 2025 01:36

He's on vacation.

@duckki duckki merged commit cf56560 into next Jul 10, 2025
17 checks passed
@duckki duckki deleted the bnjjj/add_cache_key branch July 10, 2025 01:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants