I have a federated graph that was working well, resolving entities from external services properly, the gateway doing his job.
After migrating one of my services who provide a subgraph to use ApolloServer4, the reference resolvers are no longer called on that service.
I have also tried querying for an entity directly on that service’s graphql endpoint (as opposed to through the gateway) and it’s not able to return anything except the @key and __typename
query ($representations: [_Any!]!) {
_entities(representations: $representations) {
... on User {
id
email
__typename
}
}
}
variables = {
"representations": [
{
"__typename": "User",
"id": 75
}
]
}
returns error:
{
"message": "Cannot return null for non-nullable field User.email.",
"path": [
"_entities",
0,
"email"
]...
}
The type and resolver looks like:
const typeDefs = gql`
type User @key(fields: "id") {
id: ID!
email: String!
}
`;
const UserResolver = {
id: user => user.id,
email: user => user.email,
__resolveReference: async reference => {
return UserModel.findOne({
where: { id: reference.id }
})}
}
const userSchema = {typeDefs, resolvers: {User: UserResolver}}
We are then using buildSubgraphSchema from @apollo/subgraph and schemaComposer from graphql-compose to generate the schema like so
const monolithSchema = new GraphQLSchema({
query: new GraphQLObjectType({
name: "Root",
fields: () => ({})
})
});
const typeDefsStr = printSchema(monolithSchema);
const monolithTypeDefs = gql(typeDefsStr);
const monolithResolvers = createResolversMap(monolithSchema);
let schema = buildSubgraphSchema([
{
typeDefs: monolithTypeDefs,
resolvers: monolithResolvers
},
...userSchema,
]);
schemaComposer.merge(schema);
schemaComposer
.getOTC("User")
.setDirectives([{ name: "key", args: { fields: "id" } }]);
schemaComposer.setDescription("Description");
const schema = schemaComposer.buildSchema();
This is all mostly unchanged after the ApolloServer4 upgrade.
Our ApolloServer definition looks like
const apolloServer = new ApolloServer<RequestContextType>({
schema,
introspection: true,
includeStacktraceInErrorResponses: true,
formatError,
allowBatchedHttpRequests: true,
plugins: [
ObservabilityPlugin,
ApolloServerPluginLandingPageGraphQLPlayground()
],
stopOnTerminationSignals: false
})
again, mostly unchanged.
Then there was the more substantial changes for ApolloServer4 that we made using the Migrate From apollo-server-express doc
const app = express();
await apolloServer.start();
const apolloMiddleware = expressMiddleware(apolloServer, {
context: async ({ req: { tokenData, correlationId, headers } }) => {
return {
correlationId,
headers
};
}
});
app.use(
"/graphql",
buildTokenDataFromAuth0Token,
setSchemaHash,
cors<cors.CorsRequest>(),
json({ limit: "5mb" }),
apolloMiddleware
);
Thanks for helping, please let me know if I can provide more information to help you help me!