diff --git a/composition-js/src/__tests__/compose.test.ts b/composition-js/src/__tests__/compose.test.ts index e0a538fab..879161d08 100644 --- a/composition-js/src/__tests__/compose.test.ts +++ b/composition-js/src/__tests__/compose.test.ts @@ -4655,6 +4655,43 @@ describe('composition', () => { const authenticatedDirectiveExists = schema.directives().find(d => d.name === 'authenticated'); expect(authenticatedDirectiveExists).toBeUndefined(); }); + + describe('uses minimum required spec versions', () => { + function subgraphWithFederationSpecVersion(version: string) { + const schemaString = ` + extend schema @link(url: "https://specs.apollo.dev/federation/v${version}", import: ["@key"]) + + type Query { + a: A + } + + type A @key(fields: "id") { + id: ID! + } + `; + return { + typeDefs: gql`${schemaString}`, + name: 'subgraphA', + }; + } + + it.each([ + { subgraphFedVersion: "2.0", expectedJoinVersion: "0.3" }, + { subgraphFedVersion: "2.1", expectedJoinVersion: "0.3" }, + { subgraphFedVersion: "2.2", expectedJoinVersion: "0.3" }, + { subgraphFedVersion: "2.3", expectedJoinVersion: "0.3" }, + { subgraphFedVersion: "2.4", expectedJoinVersion: "0.3" }, + { subgraphFedVersion: "2.5", expectedJoinVersion: "0.3" }, + { subgraphFedVersion: "2.6", expectedJoinVersion: "0.3" }, + { subgraphFedVersion: "2.7", expectedJoinVersion: "0.4" }, + { subgraphFedVersion: "2.8", expectedJoinVersion: "0.5" }, + ])("federation -> join versions", ({ subgraphFedVersion, expectedJoinVersion }) => { + const subgraph = subgraphWithFederationSpecVersion(subgraphFedVersion); + const result = composeServices([subgraph]); + assertCompositionSuccess(result); + expect(result.supergraphSdl).toContain(`join/v${expectedJoinVersion}`); + }); + }); }); describe('@source* directives', () => { diff --git a/internals-js/src/specs/joinSpec.ts b/internals-js/src/specs/joinSpec.ts index bd45fa212..cb4640000 100644 --- a/internals-js/src/specs/joinSpec.ts +++ b/internals-js/src/specs/joinSpec.ts @@ -287,6 +287,10 @@ export class JoinSpecDefinition extends FeatureDefinition { export const JOIN_VERSIONS = new FeatureDefinitions(joinIdentity) .add(new JoinSpecDefinition(new FeatureVersion(0, 1))) .add(new JoinSpecDefinition(new FeatureVersion(0, 2))) + // Though join v0.2 supports federation v2.0 as mentioned above, we should + // still prefer join v0.3 as a minimum for all of federation v2.0-2.6 since + // v0.3 offers improvements around union members and enum values that we're + // interested in. .add(new JoinSpecDefinition(new FeatureVersion(0, 3), new FeatureVersion(2, 0))) .add(new JoinSpecDefinition(new FeatureVersion(0, 4), new FeatureVersion(2, 7))) .add(new JoinSpecDefinition(new FeatureVersion(0, 5), new FeatureVersion(2, 8)));