Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support @join__directive(graphs, name, args) directives #2894

Merged
merged 12 commits into from
Jan 12, 2024

Conversation

benjamn
Copy link
Member

@benjamn benjamn commented Dec 19, 2023

This new @join__directive directive, like other @join__ directives, is a mechanism for linking supergraph schema elements back to their originating subgraph elements.

In the case of @join__directive, the specific kind of subgraph schema elements to be linked are directive applications. In addition to its graphs: [join__Graph!]! argument, @join__directive represents the name and args of directive applications found in subgraphs, without literally reapplying the directives in the supergraph, as @composeDirective would do.

Since directive applications can appear on a variety of schema elements in subgraphs, @join__directive is allowed on a similar variety of locations in the supergraph schema (anywhere @join__type or @join__field can appear, plus on schema definitions).

In principle, this new @join__directive behavior can be enabled at the granularity of any @link specification URL, and is initially enabled for directives imported from the hypothetical https://specs.apollo.dev/source URL, as well as for any @link directives involved in those imports. This limited initial usage of @join__directive allows preserving/recovering accurate per-subgraph information about the original directive applications.

We can extend this behavior to other specification URLs in the future if it works and proves useful, and we might consider opening the behavior up to subgraph authors by allowing, say, @composeDirective to generate @join__directive applications instead of reapplying subgraph directives verbatim (as it does by default), perhaps with an optional @composeDirective(name: "someDirective", strategy: "@join__directive") argument.

One way @join__directive deviates from the rest of the @join__ directives is in taking a plural graphs: [join__Graph!]! argument, rather than a single graph: join__Graph! argument. This API allows directives that are repeated exactly in different subgraphs (same name, deep-equal arguments) to be represented with a single @join__directive directive in the supergraph (with multiple graph names in the graphs list), which tends to save a bunch of repetition of @join__directive in the supergraph.

@benjamn benjamn self-assigned this Dec 19, 2023

This comment was marked as resolved.

Copy link

netlify bot commented Dec 19, 2023

Deploy Preview for apollo-federation-docs canceled.

Name Link
🔨 Latest commit d803501
🔍 Latest deploy log https://app.netlify.com/sites/apollo-federation-docs/deploys/659d8e7bb463c600097f4f4f

Copy link

codesandbox-ci bot commented Dec 19, 2023

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.

@benjamn benjamn marked this pull request as ready for review January 2, 2024 18:42
@benjamn benjamn requested a review from a team as a code owner January 2, 2024 18:42
@benjamn
Copy link
Member Author

benjamn commented Jan 2, 2024

Marking this PR as ready for review despite known/unknown remaining gaps (reversibility, additional tests, 100% code coverage, to name a few), because I'd love some directional feedback from the team.

Copy link
Contributor

@clenfest clenfest left a comment

Choose a reason for hiding this comment

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

Also, make sure we're merging to next, rather than main.

composition-js/src/merging/merge.ts Outdated Show resolved Hide resolved
composition-js/src/merging/merge.ts Outdated Show resolved Hide resolved
composition-js/src/merging/merge.ts Outdated Show resolved Hide resolved
composition-js/src/__tests__/compose.test.ts Show resolved Hide resolved
internals-js/src/specs/sourceSpec.ts Outdated Show resolved Hide resolved
internals-js/src/specs/joinSpec.ts Outdated Show resolved Hide resolved
internals-js/src/specs/joinSpec.ts Show resolved Hide resolved
internals-js/src/specs/sourceSpec.ts Outdated Show resolved Hide resolved
internals-js/src/specs/sourceSpec.ts Outdated Show resolved Hide resolved
composition-js/src/__tests__/compose.test.ts Outdated Show resolved Hide resolved
@clenfest
Copy link
Contributor

clenfest commented Jan 8, 2024

Missed that you should add the directives in FederationMetadata in federation.ts. You need to add getters for the directives as well as adding them in allFederationDirectives.

@benjamn benjamn changed the base branch from main to next January 9, 2024 18:21
@benjamn benjamn requested a review from clenfest January 9, 2024 19:45
@benjamn benjamn merged commit 931f87c into next Jan 12, 2024
14 checks passed
@benjamn benjamn deleted the benjamn/@join__directive branch January 12, 2024 16:15
trevor-scheer pushed a commit that referenced this pull request Jan 20, 2024
This PR was opened by the [Changesets
release](https:/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to next, this PR will
be updated.


# Releases
## @apollo/[email protected]

### Minor Changes

- Implement progressive `@override` functionality
([#2911](#2911))

The progressive `@override` feature brings a new argument to the
`@override` directive: `label: String`. When a label is added to an
`@override` application, the override becomes conditional, depending on
parameters provided to the query planner (a set of which labels should
be overridden). Note that this feature will be supported in router for
enterprise users only.

Out-of-the-box, the router will support a percentage-based use case for
progressive `@override`. For example:

    ```graphql
    type Query {
      hello: String @OverRide(from: "original", label: "percent(5)")
    }
    ```

The above example will override the root `hello` field from the
"original" subgraph 5% of the time.

More complex use cases will be supported by the router via the use of
coprocessors/rhai to resolve arbitrary labels to true/false values (i.e.
via a feature flag service).

- Support `@join__directive(graphs, name, args)` directives
([#2894](#2894))

### Patch Changes

- Allow known `FeatureDefinition` subclasses to define custom subgraph
schema validation rules
([#2910](#2910))

- Updated dependencies
\[[`6ae42942b13dccd246ccc994faa2cb36cd62cb3c`](6ae4294),
[`66833fb8d04c9376f6ed476fed6b1ca237f477b7`](66833fb),
[`931f87c6766c7439936df706727cbdc0cd6bcfd8`](931f87c)]:
    -   @apollo/[email protected]
    -   @apollo/[email protected]

## @apollo/[email protected]

### Minor Changes

- Implement progressive `@override` functionality
([#2911](#2911))

The progressive `@override` feature brings a new argument to the
`@override` directive: `label: String`. When a label is added to an
`@override` application, the override becomes conditional, depending on
parameters provided to the query planner (a set of which labels should
be overridden). Note that this feature will be supported in router for
enterprise users only.

Out-of-the-box, the router will support a percentage-based use case for
progressive `@override`. For example:

    ```graphql
    type Query {
      hello: String @OverRide(from: "original", label: "percent(5)")
    }
    ```

The above example will override the root `hello` field from the
"original" subgraph 5% of the time.

More complex use cases will be supported by the router via the use of
coprocessors/rhai to resolve arbitrary labels to true/false values (i.e.
via a feature flag service).

### Patch Changes

- Updated dependencies
\[[`6ae42942b13dccd246ccc994faa2cb36cd62cb3c`](6ae4294),
[`66833fb8d04c9376f6ed476fed6b1ca237f477b7`](66833fb),
[`931f87c6766c7439936df706727cbdc0cd6bcfd8`](931f87c)]:
    -   @apollo/[email protected]
    -   @apollo/[email protected]
    -   @apollo/[email protected]

## @apollo/[email protected]

### Minor Changes

- Implement progressive `@override` functionality
([#2911](#2911))

The progressive `@override` feature brings a new argument to the
`@override` directive: `label: String`. When a label is added to an
`@override` application, the override becomes conditional, depending on
parameters provided to the query planner (a set of which labels should
be overridden). Note that this feature will be supported in router for
enterprise users only.

Out-of-the-box, the router will support a percentage-based use case for
progressive `@override`. For example:

    ```graphql
    type Query {
      hello: String @OverRide(from: "original", label: "percent(5)")
    }
    ```

The above example will override the root `hello` field from the
"original" subgraph 5% of the time.

More complex use cases will be supported by the router via the use of
coprocessors/rhai to resolve arbitrary labels to true/false values (i.e.
via a feature flag service).

- Allow known `FeatureDefinition` subclasses to define custom subgraph
schema validation rules
([#2910](#2910))

- Support `@join__directive(graphs, name, args)` directives
([#2894](#2894))

## @apollo/[email protected]

### Minor Changes

- Implement progressive `@override` functionality
([#2911](#2911))

The progressive `@override` feature brings a new argument to the
`@override` directive: `label: String`. When a label is added to an
`@override` application, the override becomes conditional, depending on
parameters provided to the query planner (a set of which labels should
be overridden). Note that this feature will be supported in router for
enterprise users only.

Out-of-the-box, the router will support a percentage-based use case for
progressive `@override`. For example:

    ```graphql
    type Query {
      hello: String @OverRide(from: "original", label: "percent(5)")
    }
    ```

The above example will override the root `hello` field from the
"original" subgraph 5% of the time.

More complex use cases will be supported by the router via the use of
coprocessors/rhai to resolve arbitrary labels to true/false values (i.e.
via a feature flag service).

### Patch Changes

- Updated dependencies
\[[`6ae42942b13dccd246ccc994faa2cb36cd62cb3c`](6ae4294),
[`66833fb8d04c9376f6ed476fed6b1ca237f477b7`](66833fb),
[`931f87c6766c7439936df706727cbdc0cd6bcfd8`](931f87c)]:
    -   @apollo/[email protected]

## @apollo/[email protected]

### Minor Changes

- Implement progressive `@override` functionality
([#2911](#2911))

The progressive `@override` feature brings a new argument to the
`@override` directive: `label: String`. When a label is added to an
`@override` application, the override becomes conditional, depending on
parameters provided to the query planner (a set of which labels should
be overridden). Note that this feature will be supported in router for
enterprise users only.

Out-of-the-box, the router will support a percentage-based use case for
progressive `@override`. For example:

    ```graphql
    type Query {
      hello: String @OverRide(from: "original", label: "percent(5)")
    }
    ```

The above example will override the root `hello` field from the
"original" subgraph 5% of the time.

More complex use cases will be supported by the router via the use of
coprocessors/rhai to resolve arbitrary labels to true/false values (i.e.
via a feature flag service).

### Patch Changes

- Updated dependencies
\[[`6ae42942b13dccd246ccc994faa2cb36cd62cb3c`](6ae4294),
[`66833fb8d04c9376f6ed476fed6b1ca237f477b7`](66833fb),
[`931f87c6766c7439936df706727cbdc0cd6bcfd8`](931f87c)]:
    -   @apollo/[email protected]
    -   @apollo/[email protected]

## @apollo/[email protected]

### Minor Changes

- Implement progressive `@override` functionality
([#2911](#2911))

The progressive `@override` feature brings a new argument to the
`@override` directive: `label: String`. When a label is added to an
`@override` application, the override becomes conditional, depending on
parameters provided to the query planner (a set of which labels should
be overridden). Note that this feature will be supported in router for
enterprise users only.

Out-of-the-box, the router will support a percentage-based use case for
progressive `@override`. For example:

    ```graphql
    type Query {
      hello: String @OverRide(from: "original", label: "percent(5)")
    }
    ```

The above example will override the root `hello` field from the
"original" subgraph 5% of the time.

More complex use cases will be supported by the router via the use of
coprocessors/rhai to resolve arbitrary labels to true/false values (i.e.
via a feature flag service).

### Patch Changes

- Updated dependencies
\[[`6ae42942b13dccd246ccc994faa2cb36cd62cb3c`](6ae4294),
[`66833fb8d04c9376f6ed476fed6b1ca237f477b7`](66833fb),
[`931f87c6766c7439936df706727cbdc0cd6bcfd8`](931f87c)]:
    -   @apollo/[email protected]

## [email protected]

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants