web-dev-qa-db-fra.com

Comment passer un paramètre de chaîne de requête ou de route à AWS Lambda à partir de Amazon API Gateway

par exemple si nous voulons utiliser 

GET /user?name=bob

ou

GET /user/bob

Comment passeriez-vous ces deux exemples en tant que paramètre à la fonction Lambda?

J'ai vu quelque chose sur la définition d'un "mappé à partir de" dans la documentation, mais je ne trouve pas ce paramètre dans la console API Gateway.

  • method.request.path.parameter-name pour un paramètre de chemin nommé parameter-name tel que défini dans la page Demande de méthode.
  • method.request.querystring.parameter-name pour un paramètre de chaîne de requête nommé parameter-name tel que défini dans la page Method Request.

Je ne vois aucune de ces options même si j'ai défini une chaîne de requête.

251
MonkeyBonkey

À partir de septembre 2017, vous n'avez plus besoin de configurer les mappages pour accéder au corps de la demande.

Tout ce que vous avez à faire est de cocher la case "Utiliser l'intégration du proxy Lambda", sous Demande d'intégration, sous la ressource.

 enter image description here

Vous pourrez alors accéder aux paramètres de requête, aux paramètres de chemin et aux en-têtes,

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
175
Jonathan

Les étapes pour que cela fonctionne sont les suivantes:

Dans la console API Gateway ...

  1. aller à Resources -> Integration Request
  2. cliquer sur l'icône plus ou modifier en regard de la liste des modèles (étrange, car le champ de modèle est déjà ouvert et le bouton ici est grisé)
  3. Tapez explicitement application/json dans le champ content-type même s'il affiche une valeur par défaut (si vous ne le faites pas, cela ne sera ni sauvegardé ni affiché de message d'erreur)
  4. mettre ceci dans le mappage d'entrée { "name": "$input.params('name')" }

  5. cliquez sur la case à cocher à côté du menu déroulant des modèles (je suppose que c'est ce qui est finalement sauvegardé)

193
MonkeyBonkey

J'ai utilisé ce modèle de mappage pour fournir des paramètres de chaîne de requête Corps, En-têtes, Méthode, Chemin d'accès et URL à l'événement Lambda. J'ai écrit un billet de blog expliquant le modèle plus en détail: http://kennbrodhagen.net/2015/12/06/how-tcreate-a-request-object-for-your-lambda-event-from- api-gateway/

Voici le modèle de mappage que vous pouvez utiliser:

{
  "method": "$context.httpMethod",
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "queryParams": {
    #foreach($param in $input.params().querystring.keySet())
    "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "pathParams": {
    #foreach($param in $input.params().path.keySet())
    "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end

    #end
  }  
}
118
kennbrodhagen

Ces jours-ci, un modèle de liste déroulante est inclus dans la console API Gateway sur AWS.

Pour votre API, cliquez sur le nom de la ressource ... puis sur GET

Développer "Modèles de mappage du corps"

Tapez 

application/json

pour Content-Type (doit être explicitement saisi) et cliquez sur la coche

Une nouvelle fenêtre s'ouvrira avec les mots "Générer le modèle" et une liste déroulante (voir image).

Sélectionner 

Demande de méthode passthrough

 enter image description here

Puis cliquez sur Enregistrer

Pour accéder aux variables, utilisez simplement la syntaxe suivante (il s’agit de Python) URL:

https://yourURL.execute-api.us-west-2.amazonaws.com/prod/confirmReg?token=12345&uid=5

Vous pouvez obtenir des variables comme suit:

from __future__ import print_function

import boto3
import json

print('Loading function')


def lambda_handler(event, context):
    print(event['params']['querystring']['token'])
    print(event['params']['querystring']['uid'])

Il n’est donc pas nécessaire de nommer explicitement ou de mapper chaque variable souhaitée.

32

La réponse acceptée a bien fonctionné pour moi, mais en développant la réponse de gimenete, je voulais un modèle générique que je pourrais utiliser pour passer en revue tous les paramètres requête/chemin/en-tête (comme des chaînes pour le moment), et j'ai trouvé le modèle suivant. Je l'affiche ici au cas où quelqu'un le trouverait utile:

#set($keys = [])
#foreach($key in $input.params().querystring.keySet())
  #set($success = $keys.add($key))
#end

#foreach($key in $input.params().headers.keySet())
  #if(!$keys.contains($key))
    #set($success = $keys.add($key))
  #end
#end

#foreach($key in $input.params().path.keySet())
  #if(!$keys.contains($key))
    #set($success = $keys.add($key))
  #end
#end

{
#foreach($key in $keys)
  "$key": "$util.escapeJavaScript($input.params($key))"#if($foreach.hasNext),#end
#end
}
24
BenV

Afin de transmettre des paramètres à votre fonction lambda, vous devez créer un mappage entre la demande API Gateway et votre fonction lambda. Le mappage est effectué dans la section Integration Request -> Mapping templates de la ressource de passerelle API sélectionnée.

Créez un mappage de type application/json, puis à droite, vous modifierez le modèle (cliquez sur le crayon).

Un modèle de mappage est en fait un modèle Velocity dans lequel vous pouvez utiliser des ifs, des boucles et bien sûr des variables. Le modèle contient ces variables sont injectées où vous pouvez accéder aux paramètres de chaîne de requête, aux en-têtes de requête, etc. individuellement. Avec le code suivant, vous pouvez recréer toute la chaîne de requête:

{
    "querystring" : "#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0)&#end$util.urlEncode($key)=$util.urlEncode($input.params().querystring.get($key))#end",
    "body" : $input.json('$')
}

Remarque: cliquez sur le symbole de vérification pour enregistrer le modèle. Vous pouvez tester vos modifications avec le bouton "test" de votre ressource. Toutefois, afin de tester les paramètres de chaîne de requête dans la console AWS, vous devrez définir les noms de paramètre dans la section Method Request de votre ressource.

Remarque: consultez le Guide de l'utilisateur Velocity pour plus d'informations sur la langue des modèles Velocity.

Ensuite, dans votre modèle lambda, vous pouvez procéder comme suit pour obtenir l'analyse de la chaîne de requête:

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
19
gimenete

En essayant de répondre à une de mes propres questions ici , je suis tombé sur cette astuce.

Dans le modèle de mappage API Gateway, utilisez ce qui suit pour vous donner la chaîne de requête complète telle que envoyée par le client HTTP:

{
    "querystring": "$input.params().querystring"
}

L'avantage est que vous n'avez pas à vous limiter à un ensemble de clés mappées prédéfinies dans votre chaîne de requête. Vous pouvez maintenant accepter toutes les paires clé-valeur de la chaîne de requête, si c'est ce que vous voulez gérer. 

Remarque: Selon this , seul $input.params(x) est répertorié en tant que variable rendue disponible pour le modèle VTL. Il est possible que les internes changent et que querystring ne soit plus disponible.

15
user3526

Vous devriez maintenant pouvoir utiliser le nouveau type d'intégration de proxy pour Lambda pour obtenir automatiquement la demande complète sous forme standard, plutôt que de configurer des mappages.

voir: http://docs.aws.Amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration- on-proxy-resource

11
Jack Kohn - AWS

GET/utilisateur? Name = bob

{
    "name": "$input.params().querystring.get('name')"
}

GET/utilisateur/bob

{
    "name": "$input.params('name')"
}
4
Dmitry Grinko

Beaucoup de réponses ici sont excellentes. Mais je voulais quelque chose d'un peu plus simple ... Je voulais quelque chose qui fonctionnera gratuitement avec l'échantillon "Hello World". Cela signifie que je voulais qu'un simple produise un corps de requête correspondant à la chaîne de requête:

{
#foreach($param in $input.params().querystring.keySet())
  "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
#end
}

Je pense que la meilleure réponse produit quelque chose de plus utile lors de la création de choses réelles, mais pour obtenir un monde de salut rapide fonctionnant à l'aide du modèle AWS, cela fonctionne très bien.

4
KrisTC

L'exemple de mappage de paramètres suivant transmet tous les paramètres, y compris le chemin d'accès, la chaîne de requête et l'en-tête, jusqu'au noeud final d'intégration via une charge JSON.

#set($allParams = $input.params())
{
  "params" : {
    #foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
    "$type" : {
      #foreach($paramName in $params.keySet())
      "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
      #if($foreach.hasNext),#end
      #end
    }
    #if($foreach.hasNext),#end
    #end
  }
}

En effet, ce modèle de mappage génère tous les paramètres de demande dans la charge utile, comme indiqué ci-après:

{
  "parameters" : {
     "path" : {    
       "path_name" : "path_value", 
       ...
     }
     "header" : {  
       "header_name" : "header_value",
       ...
     }
     'querystring" : {
       "querystring_name" : "querystring_value",
       ...
     }
   }
}

Copié à partir de Amazon API Gateway Guide du développeur

4
matsev

La chaîne de requête est simple à analyser en javascript dans le lambda 

pour GET/user? name = bob

 var name = event.params.querystring.name;

Cela ne résout cependant pas la question utilisateur/bob de GET.

2
Michael Riecken

La fonction Lambda attend une entrée JSON. Par conséquent, l'analyse de la chaîne de requête est nécessaire. La solution consiste à modifier la chaîne de requête en JSON à l'aide du modèle de mappage.
Je l'ai utilisé pour C # .NET Core, donc l'entrée attendue doit être un JSON avec le paramètre "queryStringParameters". 
Suivez ces 4 étapes ci-dessous pour y parvenir:

  1. Ouvrez le modèle de mappage de votre ressource API Gateway et ajoutez le nouveau application/json content-tyap:

 API Gateway mapping template

  1. Copiez le modèle ci-dessous, qui analyse la chaîne de requête en JSON, et collez-le dans le modèle de mappage:

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. Dans la passerelle API, appelez votre fonction Lambda et ajoutez la chaîne de requête suivante (pour l'exemple): param1=111&param2=222&param3=333

  3. Le modèle de mappage doit créer la sortie JSON ci-dessous, qui est la contribution pour votre fonction Lambda. 

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. Vous avez terminé. À ce stade, la logique de votre fonction Lambda peut utiliser les paramètres de chaîne de requête.
    Bonne chance!

1
Lior Kirshner

Comme la réponse de @ Jonathan, après marquer Utiliser l'intégration du proxy Lambda dans Demande d'intégration , vous devez implémenter dans votre code source le format suivant: by pass 502 Bad Gateway error.

NodeJS 8.10:

exports.handler = async (event, context, callback) => {
  // TODO: You could get path, parameter, headers, body value from this
  const { path, queryStringParameters, headers, body } = event;

  const response = {
    "statusCode": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "body": JSON.stringify({
      path, 
      query: queryStringParameters,
      headers,
      body: JSON.parse(body)
    }),
    "isBase64Encoded": false
  };

  return response;
};

N'oubliez pas de déployer votre ressource à la passerelle API avant de réexécuter votre API . Réponse Le JSON de réponse ne fait que renvoyer le paramètre défini dans body est correct . , en-têtes, valeur corporelle de l'événement

const {chemin, queryStringParameters, en-têtes, corps} = événement;

0
Long Nguyen

Vous pouvez utiliser Lambda comme "Intégration du proxy Lambda", référez-vous à cette [ https://docs.aws.Amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple- proxy-for-lambda.html # api-gateway-proxy-integration-lambda-function-python] , les options disponibles pour ce lambda sont 

Pour Nodejs Lambda 'Event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables', Et 'event.requestContext'

Pour Python Lambda , Event ['headers'] ['parametername'] et ainsi de suite

0
RajDev