#node.js #express #redis #apollo-server
Вопрос:
Я пытаюсь настроить систему кэширования для своего сервера apollo Express, но, похоже, руководства, которым я следовал, взяты из официальных документов: https://www.apollographql.com/docs/apollo-server/performance/caching/#memcachedredis-setup не делайте вид, что работаете на меня.
Я могу убедиться, что в моем распознавателе запроса, который продолжает попадать в журнал консоли, он попадает каждый раз, а не только один раз, а затем устанавливается кэш
// 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;
};
Вот мой код:
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;
Я также проверяю, чтобы мое веб-приложение Cache-Control: max-age=300
также отправляло заголовок в запросе graphql. Я также проверил свой сервер Redis и убедился, что после выполнения запроса graphql новые ключи не добавляются.
Я также попытался установить директиву CacheControl для типа, подобного:
type UserProfile @cacheControl(maxAge: 300) {
...
}
но и с этим не повезло. Я ценю любую помощь, спасибо!
Комментарии:
1. Есть какие-нибудь успехи с этим вообще? Мой тоже не работает — на моем сервере redis нет записей
2. @alexr89 к сожалению, нет
Ответ №1:
Используете ли вы koa или express, вам нужно будет добавить эти плагины: 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').defau<
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,
}),
],
});
Важные примечания:
- Измените этот код
context.ctx.header ? context.ctx.header.authorization
, чтобы получить идентификатор сеанса для конкретного пользователя. - Убедитесь, что
apollo-server-express
используемая вами версия запускает событияwillResolveField
для получения значений из кэша иwillSendResponse
для установки значения в кэше, когда это необходимо (потому что у меня была проблема с версией v2.25.x в Koa). - Использование
const redis = require('redis');
не будет корректно устанавливать ttl (maxAge). Поэтому, пожалуйста, убедитесьioredis
, что вместо этого вы можете установить ttl.