Skip to content

Commit

Permalink
Add support for tag spec v0.3 (#2314)
Browse files Browse the repository at this point in the history
This PR:
- Adds a tag spec definition for tag spec v0.3.
  - The only change is to add support for the `SCHEMA` location in the `@tag` directive definition.
  - This also changes composition to use tag spec v0.3 in output.
- Updates `SUPPORTED_FEATURES` to include tag v0.3 (which controls supported features during supergraph schema processing).
- Updates the federation spec to use the `@tag` directive definition of tag spec v0.3.
  - Note this change only uses that directive definition for federation spec v2.3.
  - For federation spec v2.2 and below, we maintain current behavior (which is to use the `@tag` directive definition of tag spec v0.2).
    - This is arguably a bug, as we should be using the `@tag` directive definition of tag spec v0.1 for Fed 1 instead of v0.2, but I'm guessing it's benign given no one's complained thus far (and we'd have to run checks if we wanted to change the behavior).
- Updates `TagDirective` in `@apollo/subgraph` to use the `@tag` directive definition of tag spec v0.3. 
- Updates tests.
  • Loading branch information
sachindshinde authored Jan 5, 2023
1 parent 73eb02d commit 6474916
Show file tree
Hide file tree
Showing 11 changed files with 30 additions and 8 deletions.
1 change: 1 addition & 0 deletions composition-js/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ This CHANGELOG pertains only to Apollo Federation packages in the 2.x range. The
- Error on composition when a `@shareable` field runtime types don't intersect between subgraphs: a `@shareable` field
must resolve the same way in all the subgraphs, but this is impossible if the concrete runtime types have no
intersection at all [PR #1556](https://github.com/apollographql/federation/pull/1556).
- Uses the 0.3 version of the tag spec in the supergraph, which adds `@tag` directive support for the `SCHEMA` location [PR #2314](https://github.com/apollographql/federation/pull/2314).

## 2.2.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ exports[`composing custom core directives custom tag directive works when federa
"schema
@link(url: \\"https://specs.apollo.dev/link/v1.0\\")
@link(url: \\"https://specs.apollo.dev/join/v0.3\\", for: EXECUTION)
@link(url: \\"https://specs.apollo.dev/tag/v0.2\\", as: \\"mytag\\")
@link(url: \\"https://specs.apollo.dev/tag/v0.3\\", as: \\"mytag\\")
@link(url: \\"https://custom.dev/tag/v1.0\\", import: [\\"@tag\\"])
{
query: Query
Expand All @@ -24,7 +24,7 @@ directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on
directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE
directive @mytag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
directive @mytag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA
directive @tag(name: String!, prop: String!) on FIELD_DEFINITION | OBJECT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,7 @@ describe('composing custom core directives', () => {
DirectiveLocation.ENUM_VALUE,
DirectiveLocation.INPUT_OBJECT,
DirectiveLocation.INPUT_FIELD_DEFINITION,
DirectiveLocation.SCHEMA,
], ['name']);

expectDirectiveDefinition(schema, 'mytag', [DirectiveLocation.FIELD_DEFINITION, DirectiveLocation.OBJECT], ['name', 'prop']);
Expand Down Expand Up @@ -915,6 +916,7 @@ describe('composing custom core directives', () => {
DirectiveLocation.ENUM_VALUE,
DirectiveLocation.INPUT_OBJECT,
DirectiveLocation.INPUT_FIELD_DEFINITION,
DirectiveLocation.SCHEMA,
], ['name']);

expectDirectiveDefinition(schema, 'tag', [DirectiveLocation.FIELD_DEFINITION, DirectiveLocation.OBJECT], ['name', 'prop']);
Expand All @@ -923,7 +925,7 @@ describe('composing custom core directives', () => {

expectCoreFeature(schema, 'https://custom.dev/tag', '1.0', [{ name: '@tag' }]);
const feature = schema.coreFeatures?.getByIdentity('https://specs.apollo.dev/tag');
expect(feature?.url.toString()).toBe('https://specs.apollo.dev/tag/v0.2');
expect(feature?.url.toString()).toBe('https://specs.apollo.dev/tag/v0.3');
expect(feature?.imports).toEqual([]);
expect(feature?.nameInSchema).toEqual('mytag');
expect(printSchema(schema)).toMatchSnapshot();
Expand Down
1 change: 1 addition & 0 deletions gateway-js/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This CHANGELOG pertains only to Apollo Federation packages in the 2.x range. The
- Error on composition when a `@shareable` field runtime types don't intersect between subgraphs: a `@shareable` field
must resolve the same way in all the subgraphs, but this is impossible if the concrete runtime types have no
intersection at all [PR #1556](https://github.com/apollographql/federation/pull/1556).
- Adds support for the 0.3 version of the tag spec, which adds `@tag` directive support for the `SCHEMA` location [PR #2314](https://github.com/apollographql/federation/pull/2314).

## 2.2.2

Expand Down
2 changes: 1 addition & 1 deletion gateway-js/src/__tests__/gateway/lifecycle-hooks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ describe('lifecycle hooks', () => {
// the supergraph (even just formatting differences), this ID will change
// and this test will have to updated.
expect(secondCall[0]!.compositionId).toEqual(
'ed8cb418d55e7cd069f11d093b2ea29316e1a913a5757f383cc78ed399414104',
'4644102bb30ec7e254fac2577f78137bbab156cb965973ae481f309120738ff6',
);
// second call should have previous info in the second arg
expect(secondCall[1]!.compositionId).toEqual(expectedFirstId);
Expand Down
7 changes: 6 additions & 1 deletion internals-js/src/federationSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,9 @@ const legacyFederationDirectives = [
requiresDirectiveSpec,
providesDirectiveSpec,
externalDirectiveSpec,
TAG_VERSIONS.latest().tagDirectiveSpec,
// This should really be v0.1 instead of v0.2, but we can't change this to
// v0.1 without checking whether anyone relied on the v0.2 behavior.
TAG_VERSIONS.find(new FeatureVersion(0, 2))!.tagDirectiveSpec,
extendsDirectiveSpec,
];

Expand Down Expand Up @@ -160,6 +162,9 @@ export class FederationSpecDefinition extends FeatureDefinition {
name: FederationDirectiveName.INTERFACE_OBJECT,
locations: [DirectiveLocation.OBJECT],
}));
this.registerDirective(
TAG_VERSIONS.find(new FeatureVersion(0, 3))!.tagDirectiveSpec
);
}
}

Expand Down
1 change: 1 addition & 0 deletions internals-js/src/supergraphs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const SUPPORTED_FEATURES = new Set([
'https://specs.apollo.dev/join/v0.3',
'https://specs.apollo.dev/tag/v0.1',
'https://specs.apollo.dev/tag/v0.2',
'https://specs.apollo.dev/tag/v0.3',
'https://specs.apollo.dev/inaccessible/v0.1',
'https://specs.apollo.dev/inaccessible/v0.2',
]);
Expand Down
11 changes: 10 additions & 1 deletion internals-js/src/tagSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export class TagSpecDefinition extends FeatureDefinition {
DirectiveLocation.INPUT_FIELD_DEFINITION,
);
this.printedTagDefinition = 'directive @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION';
if (!this.isV02()) {
this.tagLocations.push(DirectiveLocation.SCHEMA);
this.printedTagDefinition = 'directive @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA';
}
}
this.tagDirectiveSpec = createDirectiveSpecification({
name:'tag',
Expand All @@ -48,6 +52,10 @@ export class TagSpecDefinition extends FeatureDefinition {
return this.version.equals(new FeatureVersion(0, 1));
}

private isV02() {
return this.version.equals(new FeatureVersion(0, 2))
}

addElementsToSchema(schema: Schema): GraphQLError[] {
return this.addDirectiveSpec(schema, this.tagDirectiveSpec);
}
Expand Down Expand Up @@ -76,6 +84,7 @@ export class TagSpecDefinition extends FeatureDefinition {

export const TAG_VERSIONS = new FeatureDefinitions<TagSpecDefinition>(tagIdentity)
.add(new TagSpecDefinition(new FeatureVersion(0, 1)))
.add(new TagSpecDefinition(new FeatureVersion(0, 2)));
.add(new TagSpecDefinition(new FeatureVersion(0, 2)))
.add(new TagSpecDefinition(new FeatureVersion(0, 3)));

registerKnownFeature(TAG_VERSIONS);
1 change: 1 addition & 0 deletions subgraph-js/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This CHANGELOG pertains only to Apollo Federation packages in the 2.x range. The

- Adds support for the 2.3 version of the federation spec (that is, `@link(url: "https://specs.apollo.dev/federation/v2.3")`), with:
- New `@interfaceObject` directive and support for keys on interfaces.
- `@tag` directive support for the `SCHEMA` location [PR #2314](https://github.com/apollographql/federation/pull/2314).

## 2.2.0

Expand Down
5 changes: 3 additions & 2 deletions subgraph-js/src/__tests__/buildSubgraphSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,7 @@ describe('buildSubgraphSchema', () => {
const { data, errors } = await graphql({ schema, source: query });
expect(errors).toBeUndefined();
expect((data?._service as any).sdl).toMatchString(
(header.length === 0
(header.length === 0
? ''
: `
${header.trim()}
Expand Down Expand Up @@ -1226,6 +1226,7 @@ describe('buildSubgraphSchema', () => {
it('expands federation 2.3 correctly', async () => {
// For 2.3, we expect in everything from 2.2 plus:
// - the @interfaceObject directive
// - the @tag directive to additionally have the SCHEMA location
await testVersion('2.3', `
schema
@link(url: \"https://specs.apollo.dev/link/v1.0\")
Expand All @@ -1246,7 +1247,7 @@ describe('buildSubgraphSchema', () => {
directive @federation__external(reason: String) on OBJECT | FIELD_DEFINITION
directive @federation__tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
directive @federation__tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA
directive @federation__extends on OBJECT | INTERFACE
Expand Down
1 change: 1 addition & 0 deletions subgraph-js/src/directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const TagDirective = new GraphQLDirective({
DirectiveLocation.ENUM_VALUE,
DirectiveLocation.INPUT_OBJECT,
DirectiveLocation.INPUT_FIELD_DEFINITION,
DirectiveLocation.SCHEMA,
],
isRepeatable: true,
args: {
Expand Down

0 comments on commit 6474916

Please sign in to comment.