-
Notifications
You must be signed in to change notification settings - Fork 257
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
Adds @tag
definition automatically in buildSubgraphSchema
#1600
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,8 @@ import { | |
GraphQLUnionType, | ||
GraphQLObjectType, | ||
specifiedDirectives, | ||
visit, | ||
GraphQLDirective, | ||
} from 'graphql'; | ||
import { | ||
GraphQLSchemaModule, | ||
|
@@ -30,6 +32,23 @@ type LegacySchemaModule = { | |
|
||
export { GraphQLSchemaModule }; | ||
|
||
function missingFederationDirectives(modules: GraphQLSchemaModule[]): GraphQLDirective[] { | ||
// Copying the array as we're going to modify it. | ||
const missingDirectives = federationDirectives.concat(); | ||
for (const mod of modules) { | ||
visit(mod.typeDefs, { | ||
DirectiveDefinition: (def) => { | ||
const matchingFedDirectiveIdx = missingDirectives.findIndex((d) => d.name === def.name.value); | ||
if (matchingFedDirectiveIdx >= 0) { | ||
missingDirectives.splice(matchingFedDirectiveIdx, 1); | ||
} | ||
return def; | ||
} | ||
}); | ||
} | ||
return missingDirectives; | ||
} | ||
|
||
export function buildSubgraphSchema( | ||
modulesOrSDL: | ||
| (GraphQLSchemaModule | DocumentNode)[] | ||
|
@@ -67,7 +86,7 @@ export function buildSubgraphSchema( | |
modules, | ||
new GraphQLSchema({ | ||
query: undefined, | ||
directives: [...specifiedDirectives, ...federationDirectives], | ||
directives: [...specifiedDirectives, ...missingFederationDirectives(modules)], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if I understand correctly, we are going through the AST to figure out which federation directives are not present and then passing them in a list? Can you explain why it isn't the federation directives that are present that we want? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When we visit the AST, we only look at directive definitions, not application. And what we're adding is the directives definition that don't already have a definition in the user provided schema. We're not looking at applications at all. Which does mean we may be adding The problem we're solving with this is that we want the |
||
}), | ||
); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -110,23 +110,13 @@ export const federationDirectives = [ | |
ProvidesDirective, | ||
ShareableDirective, | ||
LinkDirective, | ||
TagDirective, | ||
]; | ||
|
||
export function isFederationDirective(directive: GraphQLDirective): boolean { | ||
return federationDirectives.some(({ name }) => name === directive.name); | ||
} | ||
|
||
export const otherKnownDirectives = [TagDirective]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Quick note for reviewers: an option could have been to keep that notion of "known but not officially federation" directives but have it empty for now. But if anything, we're trying to move away from hard-coded directives and toward There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree that it's better to delete code that is unused rather than having it hand around! |
||
|
||
export const knownSubgraphDirectives = [ | ||
...federationDirectives, | ||
...otherKnownDirectives, | ||
]; | ||
|
||
export function isKnownSubgraphDirective(directive: GraphQLDirective): boolean { | ||
return knownSubgraphDirectives.some(({ name }) => name === directive.name); | ||
} | ||
|
||
export type ASTNodeWithDirectives = | ||
| FieldDefinitionNode | ||
| InputValueDefinitionNode | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May not matter too much, but it would probably be better to use a set to avoid the O(n) lookup in a loop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it's one those rare case where the array size is not dynamic, we know exactly how many elements the array, it's a very small number and we kind of know it's never going to grow to a large number (relatively). So complexity argument kind of don't apply, and I'd be surprise if the array version is not as fast if not faster (but I agree it doesn't matter either way in practice).