mercurius: Using fastify-gql in place of Apollo Gateway does not work
Hi,
As a proof of concept, I tried taking this demo repository and replace Apollo Gateway with fastify-gql. The federated services start fine (as expected). Then, when I try to start the Gateway server, I get this error:
Error: The directive "@key" can only be used once at this location.
at assertValidSDLExtension (/Users/julienheller/projects/federation-demo/node_modules/graphql/validation/validate.js:124:11)
at extendSchema (/Users/julienheller/projects/federation-demo/node_modules/graphql/utilities/extendSchema.js:78:45)
at buildFederationSchema (/Users/julienheller/projects/federation-demo/node_modules/fastify-gql/lib/federation.js:253:22)
at buildGateway (/Users/julienheller/projects/federation-demo/node_modules/fastify-gql/lib/gateway.js:151:18)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async fp.name (/Users/julienheller/projects/federation-demo/node_modules/fastify-gql/index.js:119:15)
My guess is that both the original definition for Product and its extended clause have a @key directive, which are trying to be merged together. I wonder how Apollo handles this situation?
Here’s my fork to try it for yourself.
npm i
npm run start-services
npm run start-fastify-gateway
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 15 (4 by maintainers)
I’ve spent more time debugging this, and I have come to the conclusion that my understanding of the issue as expressed in the previous message was incomplete.
Here’s my new understanding:
gets added to the schema as is, still retaining the
@keypart 2. Apollo-server overcomes the error we are getting by callingextendSchemawith the optionassumeValidSDLas @flux627 suggested at one point. See it here: https://github.com/apollographql/apollo-server/blob/00887a1e57a26075483ba397098f6d088a706499/packages/apollo-federation/src/composition/compose.ts#L373 3. Apollo-server however add its own validations before extending the schema: https://github.com/apollographql/apollo-server/blob/00887a1e57a26075483ba397098f6d088a706499/packages/apollo-federation/src/composition/compose.ts#L371. It uses a private function fromgraphql-js:validateSDL. It’s the same function function used internally by validateSchema, but apollo-server replaces the rules it usesI’m working on a PR to replicate the behaviour by calling
extendSchemawithassumeValidSDLset to true but also adding the validations.Let me rephrase that. The Apollo docs clearly state that when extending entities, the
extendmust include the same@keydirective as the original type definition. This is the case for stubs and actual extensions.As far as I can see, this is not the case - or at least it’s not enforced at the
graphql-jslevel. Fastify-gql builds the schema inbuildFederationSchema(https://github.com/mcollina/fastify-gql/blob/master/lib/federation.js#L230). In there the concatenation of the schemas from the federated services is parsed and then split in type stubs, extensions and definitions. It then proceed to make a call to extendSchema with each of those three groups.The error we get in the demo repository (and also in fastify-gql own example in https://github.com/mcollina/fastify-gql/blob/master/examples/gateway-subscription.js) is thrown by the call to
extendSchemathat tries to add all extensions at the same time. This happens regardless of how many type extensions with the same@keydirective have been added beforehand: the problem is just with callingextendSchemawith the extend for the same type with the same directive.To prove that I made this small change https://github.com/mcollina/fastify-gql/pull/221/files#diff-d9185daf57698ed90d572d1966e61b16R253-R258 where extensions are added one at the time and that fixed the issue: a sign that
extendSchemais accepting multiple extend with the same key directive if each one happens in their own call toextendSchemaI agree with this. Regardless of what is actually causing the exception we are seeing, the correct implementation would be to replicate the behaviour of Apollo, which is to strip the directives in the federated schema.
I took a look at Apollo’s code and that appears to be happening in https://github.com/apollographql/apollo-server/blob/5bab3aedeeb1e70c636f3aa3ac7a147679f450f7/packages/apollo-federation/src/composition/normalize.ts#L20 (more specifically in https://github.com/apollographql/apollo-server/blob/5bab3aedeeb1e70c636f3aa3ac7a147679f450f7/packages/apollo-federation/src/composition/normalize.ts#L270).
So, to sum up my point:
parseandextendSchemafromgraphql-jsweird: a schema parsed without errors byparsethrows and error inextendSchema, and that also depends on the fact that you make only one call or multiple calls to it. May be worth further investigating into this and report tographql-jsfastify-gqlshould replicate Apollo’s behaviour and strip the directives