[ ] Regression
[x] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
I'm trying to build multiple GraphQL Microservices (Experience Service and Company Service) by using Apollo Federation and code-first approach.
I've followed this documentation: https://docs.nestjs.com/graphql/federation#federation
Basically:
https://github.com/keadex/keadex-einaudi/blob/0.0.1/apps/company/src/models/experience.model.ts
@Schema()
@ObjectType()
@Directive('@extends')
@Directive('@key(fields: "_id")')
export class Experience {
@Field(() => String)
@Directive('@external')
_id: MongooseSchema.Types.ObjectId;
@Field(() => [Company])
@Prop({ type: [MongooseSchema.Types.ObjectId], ref: Company.name })
companies: MongooseSchema.Types.ObjectId[] | Company[];
}
The problem is that, the autogenerated GraphQL Schema ignores all the Directives, included the @extends one:
# ------------------------------------------------------
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
# ------------------------------------------------------
directive @extends on INTERFACE | OBJECT
directive @external on FIELD_DEFINITION | OBJECT
directive @key(fields: String!) on INTERFACE | OBJECT
directive @provides(fields: String!) on FIELD_DEFINITION
directive @requires(fields: String!) on FIELD_DEFINITION
...
type Experience {
_id: String!
ciao: String!
companies: [Company!]!
}
...
With the code-first approach I expect that NestJS, during the generation of the GraphQL Schema, takes into account all the directives added inside the model, autogenerating so a schema like the following one:
extend type User @key(fields: "id") {
id: ID! @external
posts: [Post]
}
The repo with the full code (Experience Service, Company Service, Gateway) is the following one: https://github.com/keadex/keadex-einaudi/tree/0.0.1
This is the Experience model (which extends the one inside the Experience Service - https://github.com/keadex/keadex-einaudi/blob/0.0.1/apps/experience/src/models/experience.model.ts) inside the Company Service: https://github.com/keadex/keadex-einaudi/blob/0.0.1/apps/company/src/models/experience.model.ts
Is not possible to extend GraphQL types and create GraphQL microservices separated by concern leveraging on Apollo Federation.
Nest version: 7.6.0
For Tooling issues:
- Node version: 12.13.0
- Platform: Windows
Can you make a minimum reproduction that doesn't have the database dependency? Is this only for federation or does it happen for regular GQL too?
I created two branches:
https://github.com/nestjs/graphql/issues/1278#issuecomment-744287059
and the original issue https://github.com/graphql/graphql-js/issues/1343
After some investigation and reverse engineering, I think that the issue reported by @kamilmysliwiec (graphql/graphql-js#1343) has been fixed by an own implementation of Apollo.
In fact by inspecting nestjs code, the schema is autogenerated by using the printSchema utility from the graphql package (https://graphql.org/graphql-js/utilities/#printschema):
https://github.com/nestjs/graphql/blob/3a7468e865472bad7d9ddedc8cc7370c3b9e91a4/lib/graphql-schema.builder.ts#L106
By logging the fileContent variable, I can see exactly the (not correct - without directives) autogenerated file schema.
As stated above, Apollo has fixed the issue graphql/graphql-js#1343 in its own implementation, as also stated at the head of the code: https://github.com/apollographql/federation/blob/main/federation-js/src/service/printFederatedSchema.ts

In fact, nestjs uses that at runtime and by logging the generated schema by Apollo, I can see correctly the directives:

So in order to autogenerate from nestjs the correct GraphQL Schema (with the directives), in the following file I've changed the import of the printSchema function from graphql to @apollo/federation package:
https://github.com/nestjs/graphql/blob/3a7468e865472bad7d9ddedc8cc7370c3b9e91a4/lib/graphql-schema.builder.ts
By doing this, now the autogenerated GraphQL Schema file is correct (with the directives):
# ------------------------------------------------------
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
# ------------------------------------------------------
...
type Experience @extends @key(fields: "_id") {
_id: String! @external
companies: [Company!]!
}
...
@keadex , your solution is perfect !
Thanks a lot.
Most helpful comment
After some investigation and reverse engineering, I think that the issue reported by @kamilmysliwiec (graphql/graphql-js#1343) has been fixed by an own implementation of Apollo.
In fact by inspecting nestjs code, the schema is autogenerated by using the
printSchemautility from thegraphqlpackage (https://graphql.org/graphql-js/utilities/#printschema):https://github.com/nestjs/graphql/blob/3a7468e865472bad7d9ddedc8cc7370c3b9e91a4/lib/graphql-schema.builder.ts#L106
By logging the
fileContentvariable, I can see exactly the (not correct - without directives) autogenerated file schema.As stated above, Apollo has fixed the issue graphql/graphql-js#1343 in its own implementation, as also stated at the head of the code: https://github.com/apollographql/federation/blob/main/federation-js/src/service/printFederatedSchema.ts
In fact, nestjs uses that at runtime and by logging the generated schema by Apollo, I can see correctly the directives:
So in order to autogenerate from nestjs the correct GraphQL Schema (with the directives), in the following file I've changed the import of the
printSchemafunction fromgraphqlto@apollo/federationpackage:https://github.com/nestjs/graphql/blob/3a7468e865472bad7d9ddedc8cc7370c3b9e91a4/lib/graphql-schema.builder.ts
By doing this, now the autogenerated GraphQL Schema file is correct (with the directives):