0
votes

AWS Lambda: Comment répondre à une requête http avec un corps json dans node.js

Je dois répondre à la demande https avec le corps Json dans l'API AWS Lambda. Donc, je dois d'abord lire la demande de corps et obtenir des données, puis récupérer des valeurs à partir d'une source externe (api) en fonction de ces données et renvoyer la réponse.

J'ai commencé par ceci:

const id_ses =  event.queryResult.outputContexts[0].name;
console.log(id_ses);

Lorsque je ne lis pas le corps de la demande, je peux envoyer une réponse ... mais si j'essaie d'obtenir des données du corps de la demande, je ne peux pas répondre après cela signifie que si je mets ces deux lignes

exports.handler = async (event) => {
    const id_ses =  event.queryResult.outputContexts[0].name;
    console.log(id_ses);
    const res = {
        statusCode: 200,
        body: JSON.stringify(data),
    };
    console.log(res);
    return  res;
};
//var response = { .... json response

Je ne peux pas sortir la réponse du côté demandé à l'extérieur de Lambda ... même si j'ai un bon résultat en console de test ...

Toute connaissance ou lien où je peux voir un échantillon serait bien ....


0 commentaires

3 Réponses :


0
votes

Vous pouvez utiliser une structure comme celle ci-dessous pour commencer:

Dans le code suivant, j'utilise deux fonctions comme Handler et la fonction sendToApi .

Dans la fonction de gestionnaire, il obtient la demande d'AWS Lambda et lit le corps, et transmet le paramètre de nom à l'intérieur du corps JSON à la fonction sendToApi . Ensuite, la fonction sendToApi envoie une nouvelle requête à l'API externe et récupère les valeurs, et la renvoie à la fonction de gestionnaire via `result variable. Ensuite, le gestionnaire sert la réponse.

module.exports.handler = async(event) => {
    const req = JSON.parse(event.body);
    const data = {
        name: req.name
    }
    const result = sendToApi(data);
    return {
        statusCode: 200,
        body: JSON.stringify(result),
      };
}

const sendToApi = (data) => {
    return new Promise((resolve, reject) => {
      let dataString = "";
  
      const options = {
        hostname: "example.com",
        path: "/api/v1",
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
      };
  
      const req = https.get(options, (res) => {
        res.on("data", (chunk) => {
          dataString += chunk;
        });
  
        res.on("end", (chunk) => {
          dataString = JSON.parse(dataString);
          resolve(dataString);
        });
  
        res.on("error", (e) => {
          console.error(e);
          reject(false);
        });
      });
  
      req.write(querystring.stringify(data));
  
      req.end();
    });
  };

Pour en savoir plus: https://medium.com/better-programming/aws-tutorial-about-node-js-lambda-external-https-requests-logging-and-analyzing-data-e73137fd534c


19 commentaires

J'ai utilisé l'échantillon @Harshana Serasinghe, mais j'ai un statut en attente pour la requête https plus de 3 secondes, j'ai approuvé la fonction indépendante pour cette requête https qui fonctionne bien et j'utilise les mêmes paramètres à l'intérieur .. Je vérifiais avec console.log et bloqué sur la lecture des options d'en-tête .. et la ligne de fin n'est pas également reconnue "req.write (queryString.stringify (data));"


avez-vous importé la bibliothèque de querystring ?


non, je vais essayer maintenant ... Est-il possible que dans AWS lambda?


Oui, je l'ai fait maintenant, c'est comme ça const querystring = require ('querystring'); "


voyez-vous un résultat différent ou des erreurs?


Rien ne se passe ...: (Je posterai le code si vous pouvez vérifier où je me trompe


Veuillez mettre à jour votre question avec le code. Je vais essayer d'aider :)


en attente de la requête http


Quel est le délai d'expiration par défaut de votre fonction Lambda?


3 secondes, devrais-je augmenter ... quand j'exécute cette demande par celle-ci, cela prend moins de sec


Oui, augmentez-le au maximum et vérifiez


hm ... Je pense que l'un des problèmes c'est avec l'échantillon de configuration de test (ils doivent avoir deux modèles différents), si je passe à un autre, la première partie prend beaucoup de temps et une erreur à la fin ... et l'autre Le problème pourrait être avec les autorisations iam ou certains paramètres de l'application sur lesquels ils sont déclenchés, la requête http bicaoouse fonctionne parfaitement en elle-même ... donc je vais probablement devoir utiliser la méthode d'appel ???? ... n'importe quelle idée ou votre opinion. ...


Je ne pense pas que ce soit une erreur d'autorisation IAM. Que se passe-t-il lorsque vous modifiez le délai d'expiration?


êtes-vous en ligne ..... @Harshana Serasinghe


J'ai envoyé une version un peu différente du code, seriez-vous heureux de jeter un coup d'œil?


Vérifié. J'ai quelques questions: 1. Où voyez-vous l'état en pending ? Est-ce dans la console développeur Chrome ou dans la console Node Js? 2. Voyez-vous des journaux dans la console node js? . Btw, veuillez ajouter le code mis à jour à la question. Actuellement, vous utilisez la section des réponses pour ajouter de nouvelles mises à jour. :)


dans le navigateur (mozila) j'ai "jeton d'authentification manquant" , dans la console de fonction AWS je reçois le statut en attente ... désolé d'avoir envoyé le code mis à jour comme réponse, je suis nouveau ici et je ne suis pas maintenant tous les rools


:) J'ai trouvé une erreur ... La requête https devrait être const req = https.get (options, (res) => {.... au lieu de: const req = https.request (options, (res) => {. .. ... merci pour votre soutien et veuillez mettre à jour votre réponse car elle peut être marquée comme réponse


C'est bon à entendre. J'ai mis à jour la question. S'il vous plaît laissez-moi savoir si vous avez besoin d'aide :)



0
votes

J'ai fait quelques changements comme @Harshana Serasinghe l'a suggéré

Response:
{
  "errorMessage": "2020-11-16T07:14:52.380Z 56562158-c4c3-480a-8dbe-11aacc035dab Task timed out after 3.00 seconds"
}
{
  method: 'GET',
  hostname: 'app.respond.io',
  path: '/api/v1/contact/YXM2cTBOtpVFBEdz09',
  headers: {
    Authorization: 'Bearer xxxxxxxxxxxxxx',
    'Content-Type': 'Application/json'
  }
}
END RequestId: 56562158-c4c3-480a-8dbe-11aacc035dab

Erreur:

    module.exports.handler = async (event) => {
    //const req = JSON.parse(event.body);
    //const req = event.body;
    var id_ses = event.queryResult.outputContexts[0].name;
    console.log(id_ses);
    const id_set = {
        name: 'xxxxxxxx'
    };
    const id_cont = {
        name: 'xxxxxxxxx'
    };        
    const result = await sendToApi(id_cont);
    console.log(result);
    return {
        statusCode: 200,
        body: JSON.stringify(result),
      };
};

const sendToApi = (id_cont) => {
    console.log(id_cont);
    console.log('starting respondioooo');

    var https = require('https');
    const queryString = require('querystring');
    
    return new Promise((resolve, reject) => {
        const options = {
        method: 'GET',
        hostname: 'app.respond.io',
        path: '/api/v1/contact/xxxxxxxx',
        headers: {
            'Authorization': 'Bearer xxxxxxxx',
            'Content-Type': 'Application/json'
        }
        //,
        //'maxRedirects': 20
    };
    console.log(options)
    const req = https.request(options, (res) => {
        let body = '';
        console.log('Status:', res.statusCode);
        console.log('Headers:', JSON.stringify(res.headers));
        res.setEncoding('utf8');
        res.on('data', (chunk) => body += chunk);
        res.on('end', (chunk) => {
            console.log('Successfully processed HTTPS response');
            body = JSON.parse(body);
            body = body.data.custom_fields.discount;
            body = body.replace("%","");
            console.log(body);
            resolve(body);  
      
        res.on("error", (e) => {
          console.error(e);
          reject(false);
        });
      });
      req.write(queryString.stringify(id_cont));
      req.write(body);
      req.end();
    });
  })};

ça colle ici


0 commentaires

0
votes

J'ai essayé de changer le code selon les instructions AWS:

var https = require('https');

exports.handler = async function(event) {
    const promise = await new Promise(function(resolve, reject) {        
            console.log(id_cont);
            console.log('starting respondioooo');
            const options = {
                method: 'GET',
                hostname: 'app.respond.io',
                path: '/api/v1/contact/YXM2cTBOUVErST',
                headers: {
                    'Authorization': 'Bearer c5dd82fb9d146a1abb1d149909d816e1046497a54',
                    'Content-Type': 'Application/json'
                },
                'maxRedirects': 20
            };
            console.log(options);
            
            const req = https.request(options, (res) => {
                let body = '';
                console.log('Status:', res.statusCode);
                console.log('Headers:', JSON.stringify(res.headers));
                res.setEncoding('utf8');
                res.on('data', (chunk) => body += chunk);
                res.on('end', (chunk) => {
                    console.log('Successfully processed HTTPS response');
                    body = JSON.parse(body);
                    body = body.data.custom_fields.discount;
                    body = body.replace("%","");
                    console.log(body);
                    resolve(body);  
                });
                res.on('error', (e) => {
                    reject(Error(e));
                });
                req.end();         
            });
             
        console.log(promise);
        return promise; 
};

EN:

const https = require('https')
let url = "https://docs.aws.amazon.com/lambda/latest/dg/welcome.html"

exports.handler = async function(event) {
  const promise = new Promise(function(resolve, reject) {
    https.get(url, (res) => {
        resolve(res.statusCode)
      }).on('error', (e) => {
        reject(Error(e))
      })
    })
  return promise
}

un état en attente sur la demande https pendant plus de 60 secondes ...

Une idée de ce qui ne va pas ???


0 commentaires