Skip to content

Commit 81c3fbd

Browse files
committed
tests: Demonstrate composition failure with preserved TypeSystemDirectives.
> Note: This is not the solution, just a test that demonstrates the failure! Recently, the beginnings of [Executable directive] support were brought into federation through #3464 and its follow-up, #3536. The implementation of executable directives currently in place within federation requires that federated directives be declared identically across all implementing services, even if their implementation is different (or a no-op). This is working as intended! However, [Type system directives] need some additional pruning from the composed schema. Specifically, while type system directive declarations don't need to be declared identically across implementing services, their _definitions_ are currently (intentionally!) removed from the composed schema. That would be fine, but the _usages_ of those directives are currently being left in-tact, which results in validation errors within composed schemas since the directives, while still defined in the implementing services, have been removed. It's certainly important that the implementing services maintain those type system directives in order to act upon them within the services themselves, I don't believe those directives need to be preserved in the composed schema that runs at the gateway and is used to generate the query plan. This commit is mostly documenting a reproduction of an issue that was brought to my attention and introduces what I believe is a test case to build a solution against. [Type system directive]: https://graphql.github.io/graphql-spec/draft/#TypeSystemDirectiveLocation [Executable directive]: https://graphql.github.io/graphql-spec/draft/#ExecutableDirectiveLocation
1 parent e67569f commit 81c3fbd

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

packages/apollo-federation/src/composition/__tests__/composeAndValidate.test.ts

+57
Original file line numberDiff line numberDiff line change
@@ -551,3 +551,60 @@ describe('composition of value types', () => {
551551
});
552552
});
553553
});
554+
555+
describe('composition of schemas with directives', () => {
556+
it('preserves executable and purges non-executable directives', () => {
557+
const serviceA = {
558+
typeDefs: gql`
559+
"FIELD directives are executable"
560+
directive @audit(risk: Int!) on FIELD
561+
"FIELD_DEFINITIONS directives are type-system directives"
562+
directive @transparency(concealment: Int!) on FIELD_DEFINITION
563+
564+
type EarthDirective {
565+
environmental: String! @transparency(concealment: 5)
566+
}
567+
568+
extend type Query {
569+
importantDirectives: [EarthDirective!]!
570+
}
571+
`,
572+
name: 'serviceA',
573+
};
574+
575+
const serviceB = {
576+
typeDefs: gql`
577+
"FIELD directives are executable"
578+
directive @audit(risk: Int!) on FIELD
579+
"FIELD_DEFINITIONS directives are type-system directives"
580+
directive @transparency(concealment: Int!) on FIELD_DEFINITION
581+
582+
extend type EarthDirective {
583+
societal: String! @transparency(concealment: 6)
584+
}
585+
`,
586+
name: 'serviceB',
587+
};
588+
589+
const { schema, errors } = composeAndValidate([serviceA, serviceB]);
590+
expect(errors).toHaveLength(0);
591+
592+
const audit = schema.getDirective('audit');
593+
expect(audit).toMatchInlineSnapshot(`"@audit"`);
594+
595+
const transparency = schema.getDirective('transparency');
596+
expect(transparency).toBeUndefined();
597+
598+
const fields = (schema.getType(
599+
'EarthDirective',
600+
) as GraphQLObjectType).getFields();
601+
602+
expect(fields['environmental'].astNode).toMatchInlineSnapshot(
603+
`environmental: String!`,
604+
);
605+
606+
expect(fields['societal'].astNode).toMatchInlineSnapshot(
607+
`societal: String!`,
608+
);
609+
});
610+
});

0 commit comments

Comments
 (0)