Кэшировать запрос в nodejs - PullRequest
       15

Кэшировать запрос в nodejs

0 голосов
/ 17 сентября 2018

Вот реальный код, который работает хорошо и только запрашивает API с некоторыми параметрами:

var request = require('request');
var express = require('express');
var router = express.Router();

/* GET data by sportId */
router.get('/:locale/:sportId/:federationId/:date', function(req, res) {
    var date = req.params.date;
    var locale = req.params.locale;
    var sportId = req.params.sportId;
    var federationId = req.params.federationId;

   request(getEventsOptions(sportId, federationId, date, locale), function(error, response, body) {
    res.send(body);
   });
});

// get options for request
function getEventsOptions(sportId, federationId, date, locale)
{
    return {
        url: `http://myapi.com/sporting-event/sport/${sportId}/date-from/${date}`,
       headers: {
         'accept': 'application/json',
         'dateTo': date,
         'federationIds': federationId,
         'X-Application-ID': 'sporter',
         'Accept-Language': locale,
     }
 };

}

Я получаю массив объектов (каждый объект - это спортивная игра с уникальным идентификатором события). поэтому каждый раз, когда я вызываю этот маршрут, я делаю новый вызов API, я хочу опросить API только в том случае, если объект события отличается (например, если оценка игры изменилась). У вас есть идея, как это сделать?

1 Ответ

0 голосов
/ 17 сентября 2018

Это цель, которой служит памятка .Поскольку getEventsOptions принимает скалярные аргументы, это упрощает способ его запоминания;Ключ кэша может быть вычислен из строковых аргументов, например, с помощью Lodash memoize или аналогичной реализации:

function memoize(fn, getCacheKey = ([firstArg]) => firstArg) {
  const cache = new Map();
  return (...args) => {
    const cacheKey = getCacheKey(args);

    if (!cache.has(cacheKey))
      cache.set(cacheKey, fn(...args));

    return cache.get(cacheKey);
  }
}

Предпочтительно использовать обещания, поскольку в результате объект обещания может быть кэширован, аэто будет трудно сделать с помощью обратного вызова API.Обещания предоставляются для request с официальным пакетом request-promise:

const request = require('request-promise');

function getEvents(sportId, federationId, date, locale)
{
    const options = {
        url: `http://myapi.com/sporting-event/sport/${sportId}/date-from/${date}`,
       headers: {
         'accept': 'application/json',
         'dateTo': date,
         'federationIds': federationId,
         'X-Application-ID': 'sportytrader',
         'Accept-Language': locale,
     };

     return request(options);
};

const getCachedEvents = memoize(
  getEvents,
  (...args) => JSON.stringify(args)
);

...

getCachedEvents(sportId, federationId, date, locale))
.then(body => res.send(body)
.catch(next);

Обратите внимание, что из-за того, как работает JSON.stringify, это может повлиять на то, как кешируются запросы, например, аргументы undefined и nullне различается.

...