cache = function (req, res, next) {
            function bypass() {
                debug("bypass detected, skipping cache.");
                return next();
            }

            // initial bypass chances
            if (!opt.enabled) {
                return bypass();
            }
            if (
                req.headers["x-apicache-bypass"] ||
        req.headers["x-apicache-force-fetch"] ||
        (opt.respectCacheControl && req.headers["cache-control"] == "no-cache")
            ) {
                return bypass();
            }

            // REMOVED IN 0.11.1 TO CORRECT MIDDLEWARE TOGGLE EXECUTE ORDER
            // if (typeof middlewareToggle === 'function') {
            //   if (!middlewareToggle(req, res)) return bypass()
            // } else if (middlewareToggle !== undefined && !middlewareToggle) {
            //   return bypass()
            // }

            // embed timer
            req.apicacheTimer = new Date();

            // In Express 4.x the url is ambigious based on where a router is mounted.  originalUrl will give the full Url
            let key = req.originalUrl || req.url;

            // Remove querystring from key if jsonp option is enabled
            if (opt.jsonp) {
                key = url.parse(key).pathname;
            }

            // add appendKey (either custom function or response path)
            if (typeof opt.appendKey === "function") {
                key += "$$appendKey=" + opt.appendKey(req, res);
            } else if (opt.appendKey.length > 0) {
                let appendKey = req;

                for (let i = 0; i < opt.appendKey.length; i++) {
                    appendKey = appendKey[opt.appendKey[i]];
                }
                key += "$$appendKey=" + appendKey;
            }

            // attempt cache hit
            let redis = opt.redisClient;
            let cached = !redis ? memCache.getValue(key) : null;

            // send if cache hit from memory-cache
            if (cached) {
                let elapsed = new Date() - req.apicacheTimer;
                debug("sending cached (memory-cache) version of", key, logDuration(elapsed));

                perf.hit(key);
                return sendCachedResponse(req, res, cached, middlewareToggle, next, duration);
            }

            // send if cache hit from redis
            if (redis && redis.connected) {
                try {
                    redis.hgetall(key, function (err, obj) {
                        if (!err && obj && obj.response) {
                            let elapsed = new Date() - req.apicacheTimer;
                            debug("sending cached (redis) version of", key, logDuration(elapsed));

                            perf.hit(key);
                            return sendCachedResponse(
                                req,
                                res,
                                JSON.parse(obj.response),
                                middlewareToggle,
                                next,
                                duration
                            );
                        } else {
                            perf.miss(key);
                            return makeResponseCacheable(
                                req,
                                res,
                                next,
                                key,
                                duration,
                                strDuration,
                                middlewareToggle
                            );
                        }
                    });
                } catch (err) {
                    // bypass redis on error
                    perf.miss(key);
                    return makeResponseCacheable(req, res, next, key, duration, strDuration, middlewareToggle);
                }
            } else {
                perf.miss(key);
                return makeResponseCacheable(req, res, next, key, duration, strDuration, middlewareToggle);
            }
        }
Cache a request
@param {Object} req Express request object
@param {Object} res Express response object
@param {function} next Function to call next
@returns {any}