Невозможно отправить обновленный ответ от функции обратного вызова в AWS Lambda на API-шлюз - PullRequest
0 голосов
/ 17 сентября 2018

Я создал API-шлюз, который направляет к функции AWS Lambda (узел 8.10).Функция Lambda отправляет запрос POST стороннему API и должна возвращать ответ (статус и сообщение) обратно в API GATEWAY.Происходит то, что я могу успешно вызывать сторонний API (это почтовый запрос, чтобы я мог проверить, что Lambda выполняет свою работу), но когда я отправляю ответ обратно в API GATEWAY, он не может отправить обновленный ответ.

Причина этого в том, что Lambda вызывает callback (null, response) почти сразу, тогда как ответ от стороннего API приходит позже, и, следовательно, объект ответа обновляется позже (я могу подтвердить это через консольные журналы).Я написал один обратный вызов (null, response) внутри функции обратного вызова, как видно из фрагмента прикрепленного кода, но, похоже, API GATEWAY рассматривает самый ранний ответ обратного вызова.Как я могу убедиться, что функция LAMBDA отправляет только обновленный ответ.Ниже приведен прикрепленный код:

const https = require('https');

exports.handler = async (event, context, callback) => {

  var body = JSON.parse(event.body);
  var postData = JSON.stringify(body);
  const options = {
      method: 'POST',
      hostname: app_url
      path: path_value
      port: 443,
      headers: {
          'accept': 'application/json',
          'Content-Type': 'application/json',
          'Content-Length': postData.length,
          'Authorization': auth_token_value
      }
  };

  var response = {};
  var dataStr = "";

  const req = https.request(options, (res) => {
      response.statusCode = res.statusCode;
      response.headers = res.headers;

      res.on('data', (d) => {
          dataStr += d;
      });

      res.on('end', () => {
          response.body = dataStr;
          console.log(response);
          callback(null, response);
      });
  });

  req.write(postData);
  req.end();

  console.log(response);
  callback(null, response);
}

Ответы [ 4 ]

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

Окончательный рабочий код приведен ниже.Я все еще должен вычислить нашу часть по res.headers.

const https = require('https');

exports.handler = (event, context, callback) => {

    var body = JSON.parse(event.body);
    var postData = JSON.stringify(body);
    const options = {
        method: 'POST',
        hostname: app_url,
        path: path_value,
        port: 443,
        headers: {
            'accept': 'application/json',
            'Content-Type': 'application/json',
            'Content-Length': postData.length,
            'Authorization': auth_token_value
        }
    };

    var response = {};
    var dataStr = "";

    const req = https.request(options, (res) => {
        response.statusCode = res.statusCode;
        response.headers = {}; // TODO: should be res.headers ideally

        res.on('data', (d) => {
            dataStr += d;
        });

        res.on('end', () => {
            response.body = dataStr;
            console.log(response);
            callback(null, response);
        });
    });

    req.write(postData);
    req.end();
}
0 голосов
/ 18 сентября 2018

Краткий ответ: дал AdrianT. Удалить последние две строки.

Длинный ответ: когда вы вызываете http.request (в req.end ()), вызов функции выполняется в асинхронном режиме. Это означает, что все, что функция получает в качестве параметров, будет выполнено в какой-то момент в будущем.

Но сразу после асинхронного вызова (пожар и забудьте ) функция продолжает выполнение в следующей строке. В вашем примере следующая строка - console.log, а затем обратный вызов (null, response). Вероятно, эти две строки выполняются долгое время (во времени ЦП), прежде чем сетевое отключение сделает первую часть пути к стороннему серверу.

При обратном вызове источник события лямбда информируется о результате вызова лямбды. Даже если функция продолжает свое выполнение (ожидая все еще открытых событий в цикле событий), возвращение функции уже отправлено. Таким образом, источник события, в данном случае API Gateway, понимает, что функция уже выполнила свою работу, и передает его вызывающей стороне.

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

Так как весь хаос произошел из-за асинхронной природы скрипта узла, и у меня не было никакого преимущества из-за асинхронного способа выполнения вещей здесь, в моей маленькой лямбда-функции, я закончил писать тот же код на Python (используя requestsмодуль).Теперь все работает нормально.Но мне все равно было бы интересно узнать, как я могу решить мою проблему, используя скрипт узла здесь.

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

Похоже, вам нужно удалить последние две строки (console.log и вызов функции callback), в противном случае они будут вызываться синхронно до того, как ответ на ваш запрос поступит к вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...