API, подключенный к Redis, возвращает значение при вызове cURL, но не при вызове Axios

#node.js #express #redis #axios

#node.js #экспресс #redis #axios

Вопрос:

У меня есть API ExpressJS, настроенный для обслуживания запросов от внешнего интерфейса, подключая его к моей базе данных Redis. Одна конечная точка принимает параметр, указанный в URL-адресе запроса (GET request), и возвращает число. Когда я использую Axios или Node-Fetch для попадания в эту конечную точку, он возвращает null, который возвращает Node-Redis, если ключ не существует. Когда я нажимаю на эту конечную точку с помощью cURL и Chrome, он возвращает правильное число. Другие конечные точки функционируют корректно. Почему это так?

Серверный код:

 router.get("/api/:id/bal", async (req, res) => {
    let id = req.params.id;
    await client.get(id, (err, response) => {
      if (err) throw err;
      res.send(response);
    });
  }); 
 

Вызов Axios:

 axios.get(`http://localhost:4000/api/${id}/bal`)
  .then((response) => {
     console.log(response.data);
})
 

Вызов cURL:

 curl http://localhost:4000/api/id/bal -i
 

(в обоих id заменяется на реальный идентификатор учетной записи)

Ответ №1:

Не уверен, поможет ли это, но смешивание обратных вызовов и async/await не рекомендуется. В зависимости от того, какую библиотеку redis вы используете, она может отличаться, но я предполагаю, что вы используете node-redis , что по умолчанию не указано, поэтому вам нужно придерживаться обратных вызовов:

 router.get("/api/:id/bal", (req, res, next) => {
    let id = req.params.id;
    client.get(id, (err, response) => {
      if (err) return next(err); // do not throw inside callbacks !
      // if you do nobody catch the error
      // you have to pass it to `next` to let express handle it.
      console.log('redis response:', response); // added a log so we can check the value
      res.send(response); // maybe more need to be done here, proper formating ?
    });
  });
 

Или вы можете пообещать redis самостоятельно (для этого вам нужен узел 8 и экспресс 5 ):

 const { promisify } = require("util");
const getAsync = promisify(client.get).bind(client);
router.get("/api/:id/bal", async (req, res) => {
    let id = req.params.id;
    const response = await getAsync(id);
    console.log('redis response:', response)
    res.send(response);
  });
 

здесь, поскольку мы используем async/await , ошибка будет перехвачена и обработана express без необходимости использования обратных вызовов и next !

Теперь просто проверьте журналы, если это не удается, возможно, попробуйте отправить его в формате JSON с res.json(response) помощью?

Комментарии:

1. Я обещаю использовать node-redis, поскольку имеет смысл не смешивать обратные вызовы и асинхронность / ожидание. К сожалению, он по-прежнему возвращает null при вызове axios и правильный ответ при вызове cURL

2. Тогда, вероятно, это ошибка axios , я не знаю библиотеку, поэтому здесь не могу помочь, попробуйте с помощью fetch: fetch(`http://localhost:4000/api/${id}/bal`).then(r => r.text()).then(console.log)

3. он по-прежнему возвращает null, я собираюсь попробовать использовать ioredis, чтобы посмотреть, работает ли это

4. с ioredis это все еще происходит