'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.authorizationto get session Id for specific user. - Make sure that the version of
apollo-server-expressyou use will fire eventswillResolveFieldfor getting values from the cache andwillSendResponsefor 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 useioredisinstead 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 |
