我正在设计客户端和GraphQL API之间的中间件。这个想法是创建一条路由,使所有客户端请求都到达第一个/filament
。然后,此路由决定是可以从缓存发送回数据还是继续进行/graphql
以访问那里的解析器以从数据库获取数据。我正在使用Axios发出请求,但未触发服务器端。我想问一下这是否只是使用Axios的不当方法,还是我做错了。
Server.js
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const fetch = require("node-fetch");
const redis = require("redis");
const PORT = process.env.PORT || 4000;
// const REDIS_PORT = process.env.REDIS_PORT || 6379;
//Create Redis client on Redis port (optional)
const client = redis.createClient();
const schema = require('./schema');
const bluebird = require('bluebird')
const app = express()
// bluebird.promisifyAll(redis.RedisClient.prototype);
// bluebird.promisifyAll(redis.Multi.prototype);
app.use(express.json())
client.on("error", err => {
console.log("Error " + err);
});
client.on('connect', () => {
console.log('Redis client connected');
});
// pass redis as context so our schema can use Redis methods
const wrapper = require('./filamentMiddleware')
app.use('/filament',
wrapper(client), // filamentMiddleware with access to client
)
app.use(
'/graphql',
graphqlHTTP((req) => ({
schema,
graphiql: true,
context: {
client,
req: req
}
})),
// addToCacheWrapper(res.data)
);
app.listen(PORT, () =>
console.log(`GraphQL server is running on port: ${PORT}`)
);
中间件
const axios = require('axios')
const serverFilamentQuery = require('./serverFilamentQuery')
const mergeDataFromCacheAndServer = require('./mergeDataFromCacheAndServer')
const wrapper = (client) => (req, res, next) => {
const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
client.get(ip, (err, cacheData) => {
const { query } = req.body
// ip not found in cache
if (!cacheData) {
console.log('cacheData:', cacheData)
axios.post('/graphql', { query }).then(res => {
console.log('have we made the post ????')
// set redis cache
// set the new data in Redis
client.set(ip, JSON.stringify({
todos: res.data.data['todos']
}), (err, result) => {
console.log(result)
})
const { data } = res.data
// return combinedData to client
return res.status(200).json({ data })
})
}
// console.log('ip found in cache')
const [newQuery, data, isMatched] = serverFilamentQuery(query, cacheData)
if (isMatched) {
return res.status(200).json({ data })
} else {
axios.post('/graphql', { newquery }).then(res => {
const merged = mergeDataFromCacheAndServer(data['todos'], res.data.data['todos']);
// set the new data in Redis
console.log(merged)
client.set(ip, JSON.stringify({
todos: merged
}), (err, result) => {
console.log(result)
})
// return combinedData to client
return res.status(200).json({ merged })
})
}
})
}
module.exports = wrapper