Reputation: 1909
I'd like to cache my expensive GQL queries on the server-side with nestjs
I've followed https://docs.nestjs.com/graphql/plugins#using-external-plugins and then https://www.apollographql.com/docs/apollo-server/performance/caching/#caching-with-responsecacheplugin-advanced
I've also seen https://github.com/nestjs/graphql/issues/443#issuecomment-599445224 which suggests that it should work as expected
I am using apollo federation
the problem I have is that it works (more or less) correctly if I add the responseCachePlugin inside the subgraph
However, when I try to use the responseCachePlugin at the gateway (i.e at the federation service), it simply is ignored: all the requests always hit the downstream subgraphs
package.json
"dependencies": {
...
"@nestjs/common": "^7.6.18",
"@nestjs/core": "^7.6.18",
"@nestjs/graphql": "^7.11.0",
"@nestjs/platform-express": "^7.6.18",
"apollo-server-express": "^2.25.0",
"apollo-server-plugin-response-cache": "^0.9.0",
...
"graphql": "^15.5.0",
"graphql-subscriptions": "^1.2.1",
"graphql-type-json": "^0.3.2",
...
}
Note : using 0.9.0 to be compatible with 2.25.0 (not yet the possibility to move to latest 3.2.0)
Then, in my "main" module of the gateway I have :
GraphQLGatewayModule.forRootAsync({
imports: [
LoggerModule,
BuildServiceModule,
ConfigModule.register(GwEnvVar, GW_DEFAULT_CONFIG),
],
inject: [ConfigService, GATEWAY_BUILD_SERVICE],
useFactory: (configService: ConfigService<GwEnvVar>) => ({
cors: true,
server: {
introspection:
configService.env.NODE_ENV === NodeEnv.PRODUCTION ? false : true,
playground: true,
cacheControl: {
defaultMaxAge: 5,
},
plugins: [responseCachePlugin()],
},
gateway: getSupergraphSchema('schema.gql', configService.env),
}),
}),
],
})
export class GraalModule {}
The app starts correctly but, as I already said, every request hit the downstream subgraphs
Also note that if I put the exact same config directly in subgraphs, then the resolvers are not hit anymore (however, it means the cache is done inside the subgraph which is NOT what I'd like)
If not providing directly a solution, does anyone have a pointer to explain how caching is supposed to work with apollo federation (beyond the minimalist doc https://www.apollographql.com/docs/apollo-server/performance/caching/#caching-with-responsecacheplugin-advanced and https://www.apollographql.com/docs/federation/performance/caching/) ?
Upvotes: 2
Views: 1878
Reputation: 45
I was having a similar problem (without federation) and found the following additions need to be made:
apollo-cache-control
in addition to apollo-server-plugin-response-cache
when you are not using apollo server v3+.@cacheControl
to the type's fields if they're also types, and they have to match the parent. Otherwise the cache control maxAge will use the defaultMaxAge
. For example: type Dog @cacheControl(maxAge: 100) {
dob: String,
name: String,
breed: Breed
}
type Breed @cacheControl(maxAge: 100) {
name: String!
size: Int
}
Upvotes: 0