'Can't get redis cache to work with apollo server express
I'm trying to setup a caching system for my apollo express server, but it seems like the guides I've followed from the official docs: https://www.apollographql.com/docs/apollo-server/performance/caching/#memcachedredis-setup do not appear to work for me.
I can verify that in my resolver for a query that it keeps getting hit by console logging that it is being hit each time instead of only being hit once and then the cache being set
// my resolver definition
const getUserProfile = async (_, args, context, info) => {
info.cacheControl.setCacheHint({ maxAge: 300 });
console.log('MISS, set cache hint') // this console logs every time instead of just once
return context;
};
Here is my code:
server.js
...
const redisClient = require('./cacheClient');
let httpServer;
if (process.env.ENV === 'prod') {
httpServer = httpCreateServer(app);
} else {
httpServer = httpsCreateServer(
{
key: fs.readFileSync('./localhost-key.pem'),
cert: fs.readFileSync('./localhost.pem'),
},
app
);
}
const apolloServer = new ApolloServer({
typeDefs,
resolvers,
cache: new BaseRedisCache({
client: redisClient
}),
cacheControl: true,
});
apolloServer.context = ({ req }) => ({
...
});
await apolloServer.start();
apolloServer.applyMiddleware({ app });
httpServer.listen(PORT, () =>
console.log(`Server is now running on port ${PORT}`)
);
cacheClient.js
require('dotenv').config();
const { REDIS_SERVER, REDIS_PORT } = process.env;
const redis = require('redis');
const client = redis.createClient({
host: REDIS_SERVER,
port: REDIS_PORT,
});
client.on('connect', () => {
console.log('Redis client connected');
});
client.on('message', (channel, message) => {
console.log(`Received ${message} from ${channel}`);
});
module.exports = client;
I'm also making sure my web app is sending a Cache-Control: max-age=300
header on the graphql query as well. I also checked my Redis server and verified that no new keys are added after making the graphql query.
I have also tried setting the cacheControl directive onto the type like:
type UserProfile @cacheControl(maxAge: 300) {
...
}
but no luck with that either. I appreciate any help, thank you!
Solution 1:[1]
Whether you use koa or express, you will need to add these plugins: https://www.apollographql.com/docs/apollo-server/api/plugin/cache-control/ https://www.apollographql.com/docs/apollo-server/performance/caching#identifying-users-for-private-responses
...
const responseCachePlugin = require('apollo-server-plugin-response-cache').default;
const { ApolloServerPluginCacheControl } = require("apollo-server-core");
const server = new ApolloServer({
typeDefs,
resolvers,
plugins: [responseCachePlugin({
sessionId: ({ context }) => (context.ctx.header ? context.ctx.header.authorization : null),
}),
ApolloServerPluginCacheControl({
// Cache everything for 1000 seconds.
defaultMaxAge: 1000,
// Don't send the `cache-control` response header.
calculateHttpHeaders: false,
}),
],
});
Important Notes:
- Change this code
context.ctx.header ? context.ctx.header.authorization
to get session Id for specific user. - Make sure that the version of
apollo-server-express
you use will fire eventswillResolveField
for getting values from the cache andwillSendResponse
for setting the value in cache when needed (because I had a problem with v2.25.x in Koa). - Using
const redis = require('redis');
will not set ttl (maxAge) correctly. So, please make sure to useioredis
instead to be able to set ttl.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Ehab Terra |