As part of our apollo federation, we have 3 subgraphs.
content
bookmarking
coral
In the content subgraph, we have marked around 5 entities with the @key directive and all of these entities are resolved within the content subgraph, which is extended in bookmarking. If I am querying only content subgraph using any graphql client, I am able to receive the response. but if I am querying my bookmarking service which internally resolves to my content subgraph through apollo gateway. I am able to see the fields are getting resolved to null.
Sample Code Snippet Below:
The entity of the content subgraph:
type Recipe implements IRecipe & Node & Content & HasContributors & HasMedia & HasRecommendations & HasSEO & Publishable & Recommendable @key(fields: "id organizationId"){
"""ID of the Recipe"""
id: ID!
""ID of the Organization associated with the Recipe""
organizationId: ID!
"""Headline of the Recipe"""
hed(textFormat: TEXT_FORMAT = MARKDOWN): String
.....
}
Extended in bookmarking subgraph:
type Bookmark @cacheControl(maxAge: 300) {
id: Int!
organizationId: String
copilotId: String
siteCode: String
documentUrl: String
bookmarkName: String
documentType: String
meta: String
amgUUID: String!
collections(limit: Int!, offset: Int!): [Bookmarkcollection!]!
totalCollectionCount:Int
content: DocumentType
}
union DocumentType = Article | Photo | Gallery | Recipe | NativeRecipe
extend type Recipe @key(fields: "id organizationId") {
id: ID! @external
organizationId: ID! @external
isBookmarked(amgUUID: ID!): Boolean
}
Query:
query{
bookmark(id: 547) {
amgUUID
content{
... on Recipe{
hed
}
}
}
}
Response:
{
"data": {
"bookmark": {
"amgUUID": "b44449da-bae2-4160-abc8-2fdaee4ad37d",
"content": {
"hed": null
}
}
}
}
Except for the @key directive fields id and organizationId
, the above query is not resolving other fields in the recipe content subgraph.
The field resolves if I am querying only the content subgraph.
apollo-server-koa: "2.21.1",
@graphql-tools/merge: "8.2.7",
@graphql-tools/schema: "8.5.0",
@graphql-tools/utils: "8.6.6",
graphql: "15.8.0"
@apollo/subgraph: 0.4.2
I am using the following code to compose my schema in Apollo Server.
const contentDirectiveTypeDefs = getContentDirectiveTypeDefs();
const contentSchemaTransforms = getContentDirectiveTransformers();
const sharedDirectiveTypeDefs = getSharedDirectiveTypeDefs();
const sharedSchemaTransforms = getSharedDirectiveTransformers();
const typeDefs = mergeTypeDefs([
...contentSchemas,
...contentDirectiveTypeDefs,
...sharedDirectiveTypeDefs,
Modules.schema,
]);
const resolvers = mergeResolvers([contentResolvers, Modules.resolvers]);
let schema = addResolversToSchema({
inheritResolversFromInterfaces: true,
resolvers,
schema: buildSubgraphSchema([{ typeDefs }]),
});
const directives = Modules.schemaDirectives;
SchemaDirectiveVisitor.visitSchemaDirectives(schema, directives);
contentSchemaTransforms.forEach((transformedSchema) => {
schema = transformedSchema(schema);
});
sharedSchemaTransforms.forEach((transformedSchema) => {
schema = transformedSchema(schema);
});
const apolloServer = new ApolloServer({
cache,
schema,
context: contextFunction,
dataSources: (): DataSources =>
dataSources({
cneApiDataSourceOptions: {
httpsAgent,
cache: cneApi.cache,
logger: createLogger(cneApi.log),
cneApiUrl: cneApi.cneApiUrl,
},
contentApiDataSourceOptions: {
httpsAgent,
cache: contentApi.cache,
logger: createLogger(contentApi.log),
},
ratingsApiDataSourceOptions: {
cache: ratingsApi.cache,
httpsAgent,
logger: createLogger(ratingsApi.log),
},
recommendationsApiDataSourceOptions: {
httpsAgent,
recommendationsApiUrl: recommendationsApi.recommendationsApiUrl,
logger: createLogger(recommendationsApi.log),
},
simpleRequestDataSourceOptions: {
cache: simpleRequest.cache,
httpsAgent,
logger: createLogger(simpleRequest.log),
},
tsuguApiDataSourceOptions: {
cache: tsuguApi.cache,
logger: createLogger(tsuguApi.log),
typesToResolve: tsuguApi.typesToResolve,
tsuguInstances: tsuguApi.tsuguInstances,
},
}),
validationRules: [depthLimit(queryDepthLimit)],
extensions,
debug: enableDebug,
introspection: enableIntrospection,
playground: {
settings: {
'schema.polling.enable': false,
},
} as PlaygroundConfig,
plugins: [SchemaHashPlugin],
tracing: enableTracing,
});
apolloServer.applyMiddleware({ app });
return apolloServer;
}
Apollo Gateway Query Plan:
QueryPlan {
Sequence {
Fetch(service: "bookmarking-service") {
{
bookmark(id: 0) {
amgUUID
content {
__typename
... on Recipe {
__typename
id
organizationId
}
}
}
}
},
Flatten(path: "bookmark.content") {
Fetch(service: "content") {
{
... on Recipe {
__typename
id
organizationId
}
} =>
{
... on Recipe {
hed
}
}
},
},
},
}