From 0bad61dcc23ea5c34cfcd1b2ea7b5d794962432e Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Fri, 27 Sep 2019 11:35:31 +0300 Subject: [PATCH] Use reference-equality when omitting validation rules during composition. (#3338) * Use reference-equality when omitting validation rules during composition. The previous technique for deciding which validation rules from `specifiedSDLRules` to by-pass during composition was leveraging a string-comparison against `Function.prototype.name`. As shown in https://github.com/apollographql/apollo-server/issues/3335, that technique breaks down under minification, when function names are often munged to shorter alternatives. As an alternative, we can import the rules and check them for reference equality with greater success, since those will not be affected by minification. While the actual bug in #3335 was _not_ in this code, this code poses the same hazard and would likely be affected as well (eventually, at least). * Add changelog entry --- packages/apollo-federation/CHANGELOG.md | 2 + .../src/composition/rules.ts | 66 ++++++++++++++----- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/packages/apollo-federation/CHANGELOG.md b/packages/apollo-federation/CHANGELOG.md index 69ae36a0924..d9836d6a916 100644 --- a/packages/apollo-federation/CHANGELOG.md +++ b/packages/apollo-federation/CHANGELOG.md @@ -4,6 +4,8 @@ > The changes noted within this `vNEXT` section have not been released yet. New PRs and commits which introduce changes should include an entry in this `vNEXT` section as part of their development. When a release is being prepared, a new header will be (manually) created below and the the appropriate changes within that release will be moved into the new section. +- Use reference-equality when omitting validation rules during composition. [#3338](https://github.com/apollographql/apollo-server/pull/3338) + ### v0.10.0 > [See complete versioning details.](https://github.com/apollographql/apollo-server/commit/6100fb5e0797cd1f578ded7cb77b60fac47e58e3) diff --git a/packages/apollo-federation/src/composition/rules.ts b/packages/apollo-federation/src/composition/rules.ts index fbbff121fa6..faa96bfed8b 100644 --- a/packages/apollo-federation/src/composition/rules.ts +++ b/packages/apollo-federation/src/composition/rules.ts @@ -1,27 +1,59 @@ import { specifiedSDLRules } from 'graphql/validation/specifiedRules'; +/** + * Since this module has overlapping names in the two modules (graphql-js and + * our own, local validation rules) which we are importing from, we + * intentionally are very explicit about the suffixes of imported members here, + * so that the intention is clear. + * + * First, we'll import validation rules from graphql-js which we'll omit and + * replace with our own validation rules. As noted above, we'll use aliases + * with 'FromGraphqlJs' suffixes for clarity. + */ + +import { + UniqueDirectivesPerLocation as UniqueDirectivesPerLocationFromGraphqlJs, +} from 'graphql/validation/rules/UniqueDirectivesPerLocation'; +import { + UniqueTypeNames as UniqueTypeNamesFromGraphqlJs, +} from 'graphql/validation/rules/UniqueTypeNames'; +import { + UniqueEnumValueNames as UniqueEnumValueNamesFromGraphqlJs, +} from 'graphql/validation/rules/UniqueEnumValueNames'; +import { + PossibleTypeExtensions as PossibleTypeExtensionsFromGraphqlJs, +} from 'graphql/validation/rules/PossibleTypeExtensions'; +import { + UniqueFieldDefinitionNames as UniqueFieldDefinitionNamesFromGraphqlJs, +} from 'graphql/validation/rules/UniqueFieldDefinitionNames'; + +/** + * Then, we'll import our own validation rules to take the place of those that + * we'll be customizing, taking care to alias them all to the same name with + * "FromComposition" suffixes. + */ import { - UniqueTypeNamesWithFields, - MatchingEnums, - PossibleTypeExtensions, - UniqueFieldDefinitionNames, - UniqueUnionTypes, -} from './validate/sdl'; + UniqueTypeNamesWithFields as UniqueTypeNamesWithFieldsFromComposition, + MatchingEnums as MatchingEnumsFromComposition, + PossibleTypeExtensions as PossibleTypeExtensionsFromComposition, + UniqueFieldDefinitionNames as UniqueFieldDefinitionsNamesFromComposition, + UniqueUnionTypes as UniqueUnionTypesFromComposition, + } from './validate/sdl'; const omit = [ - 'UniqueDirectivesPerLocation', - 'UniqueTypeNames', - 'UniqueEnumValueNames', - 'PossibleTypeExtensions', - 'UniqueFieldDefinitionNames', + UniqueDirectivesPerLocationFromGraphqlJs, + UniqueTypeNamesFromGraphqlJs, + UniqueEnumValueNamesFromGraphqlJs, + PossibleTypeExtensionsFromGraphqlJs, + UniqueFieldDefinitionNamesFromGraphqlJs, ]; export const compositionRules = specifiedSDLRules - .filter(rule => !omit.includes(rule.name)) + .filter(rule => !omit.includes(rule)) .concat([ - UniqueFieldDefinitionNames, - UniqueTypeNamesWithFields, - MatchingEnums, - UniqueUnionTypes, - PossibleTypeExtensions, + UniqueFieldDefinitionsNamesFromComposition, + UniqueTypeNamesWithFieldsFromComposition, + MatchingEnumsFromComposition, + UniqueUnionTypesFromComposition, + PossibleTypeExtensionsFromComposition, ]);