Skip to content

Commit

Permalink
tests: Demonstrate composition failure with preserved TypeSystemDirec…
Browse files Browse the repository at this point in the history
…tives.

> 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
  • Loading branch information
abernix committed Nov 27, 2019
1 parent e67569f commit 81c3fbd
Showing 1 changed file with 57 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -551,3 +551,60 @@ describe('composition of value types', () => {
});
});
});

describe('composition of schemas with directives', () => {
it('preserves executable and purges non-executable directives', () => {
const serviceA = {
typeDefs: gql`
"FIELD directives are executable"
directive @audit(risk: Int!) on FIELD
"FIELD_DEFINITIONS directives are type-system directives"
directive @transparency(concealment: Int!) on FIELD_DEFINITION
type EarthDirective {
environmental: String! @transparency(concealment: 5)
}
extend type Query {
importantDirectives: [EarthDirective!]!
}
`,
name: 'serviceA',
};

const serviceB = {
typeDefs: gql`
"FIELD directives are executable"
directive @audit(risk: Int!) on FIELD
"FIELD_DEFINITIONS directives are type-system directives"
directive @transparency(concealment: Int!) on FIELD_DEFINITION
extend type EarthDirective {
societal: String! @transparency(concealment: 6)
}
`,
name: 'serviceB',
};

const { schema, errors } = composeAndValidate([serviceA, serviceB]);
expect(errors).toHaveLength(0);

const audit = schema.getDirective('audit');
expect(audit).toMatchInlineSnapshot(`"@audit"`);

const transparency = schema.getDirective('transparency');
expect(transparency).toBeUndefined();

const fields = (schema.getType(
'EarthDirective',
) as GraphQLObjectType).getFields();

expect(fields['environmental'].astNode).toMatchInlineSnapshot(
`environmental: String!`,
);

expect(fields['societal'].astNode).toMatchInlineSnapshot(
`societal: String!`,
);
});
});

0 comments on commit 81c3fbd

Please sign in to comment.