Comment passer un paramètre querystring ou route à AWS Lambda depuis la passerelle de L'API Amazon

par exemple, si nous voulons utiliser

GET /user?name=bob

ou

GET /user/bob

Comment passer ces deux exemples comme paramètre à la fonction Lambda?

j'ai vu quelque chose à propos du paramétrage d'un" mapped from " dans la documentation, mais je ne trouve pas ce paramétrage dans la console de passerelle de L'API.

  • method.request.path.parameter-name pour un paramètre de chemin nommé parameter-name tel que défini dans la page de requête 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 de requête de méthode.

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

223
demandé sur Vilsepi 2015-07-10 02:20:12

17 réponses

depuis septembre 2017, vous n'avez plus besoin de configurer mappings pour accéder au corps de la requête.

Tout ce que vous devez faire est de vérifier," utiliser Lambda Proxy integration", 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 comme ça

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
131
répondu Jonathan 2017-09-08 10:19:04

les étapes pour obtenir ce fonctionnement sont:

dans la Console de passerelle API ...

  1. passer à Resources -> Integration Request
  2. cliquez sur l'icône plus ou modifiez à côté de la liste déroulante des modèles (Impair je sais puisque le champ du modèle est déjà ouvert et que le bouton ici a l'air 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, il ne sauvera pas et ne vous donnera pas un message d'erreur)
  4. mettez ceci dans la cartographie d'entrée { "name": "$input.params('name')" }

  5. cliquez sur la case à cocher à côté de la liste déroulante des modèles (je suppose que c'est ce qui sauve finalement)

184
répondu MonkeyBonkey 2017-04-24 13:43:41

j'ai utilisé ce modèle de mapping pour fournir le corps, les en-têtes, la méthode, le chemin, et les paramètres de chaîne de requête 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-to-create-a-request-object-for-your-lambda-event-from-api-gateway /

voici le modèle de cartographie 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
  }  
}
117
répondu kennbrodhagen 2015-12-07 01:26:59

de nos jours, un modèle de menu déroulant est inclus dans la console de passerelle de L'API sur AWS.

pour votre API, cliquez sur le nom de la ressource... puis obtenir

Développer "Body Mapping De Modèles"

Type

application / json

pour le type de contenu (doit être explicitement tapé) et cliquez sur le bouton

"

une nouvelle fenêtre s'ouvrira avec le mots "Generate template" et un dropdown (voir image).

sélectionner

Méthode Demande passthrough

enter image description here

puis cliquez sur Enregistrer

pour accéder à n'importe quelle variable, il suffit d'utiliser la syntaxe suivante (C'est Python) par exemple 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 cartographier chaque variable que vous désirez.

31
répondu Dirk Conrad Coetsee 2016-04-19 11:48:11

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 par tous les paramètres de requête/chemin/en-tête (tout comme les chaînes pour le moment), et je suis venu le modèle suivant. Je le poste 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
répondu BenV 2015-10-18 15:53:36

pour passer des paramètres à votre fonction lambda, vous devez créer une correspondance entre la demande API Gateway et votre fonction lambda. La mise en correspondance se fait dans la section Integration Request -> Mapping templates de la ressource API Gateway sélectionnée.

créer un mapping de type application/json , puis à droite vous éditerez (cliquez sur le crayon) le modèle.

un modèle de mapping est en fait un modèle de vélocité où vous pouvez utiliser ifs, loops et bien sûr, imprimez des variables dessus. Le modèle a ces variables injectées où vous pouvez accéder aux paramètres querystring, en-têtes de demande, etc. individuellement. Avec le code suivant, vous pouvez recréer l'ensemble de la chaîne de caractères:

{
    "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('$')
}

Note: cliquez sur le symbole de vérification pour sauvegarder le modèle. Vous pouvez tester vos modifications avec le bouton "Tester" dans votre ressource. Mais pour tester les paramètres querystring dans la console AWS vous devrez définissez les noms de paramètres dans la section Method Request de votre ressource.

Note: consultez le Velocity User Guide pour plus d'informations sur le langage de modélisation de la vitesse.

alors dans votre modèle lambda vous pouvez faire ce qui suit pour obtenir le parsed querystring:

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
18
répondu gimenete 2018-09-28 13:37:34

dans le cadre d'essayer de répondre à une de mes propres questions ici , je suis tombé sur cette astuce.

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

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

L'avantage est que vous n'avez pas à vous limiter à un ensemble prédéfini de touches repérées dans votre chaîne de requête. Maintenant, vous pouvez accepter toutes les paires clé-valeur dans la chaîne de requête, si c'est la façon dont vous souhaitez gérer.

Note: selon cette , seule $input.params(x) est listée comme une variable mise à disposition pour le modèle VTL. Il est possible que les internes puissent changer et que querystring ne soit plus disponible.

15
répondu user3526 2017-05-23 11:33:32

Maintenant, vous devriez être en mesure d'utiliser le nouveau type d'intégration de proxy pour Lambda pour obtenir automatiquement la demande complète en forme standard, plutôt que configurer mappings.

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
répondu Jack Kohn - AWS 2016-09-27 17:01:32

beaucoup de réponses ici sont grands. Mais je voulais quelque chose d'un peu plus simple. Je voulais quelque chose qui fonctionne avec L'échantillon "Hello World" gratuitement. Cela signifie que je voulais un simple produit un corps de requête qui correspond à 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 construction de quelque chose de réel, mais pour obtenir un hello world rapide fonctionnement en utilisant le modèle de AWS cela fonctionne très bien.

4
répondu KrisTC 2016-05-13 11:04:21

l'exemple suivant de mappage de paramètre passe tous les paramètres, y compris le chemin, le querystring et l'en-tête, au point 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 fait, ce modèle de mappage affiche tous les paramètres de la demande dans la charge utile comme suit:

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

copié du Amazon API Gateway Developer Guide

4
répondu matsev 2016-08-21 20:28:37

GET / user?nom = bob

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

GET /utilisateur/bob

{
    "name": "$input.params('name')"
}
3
répondu Dmitry Grinko 2017-11-28 02:28:46

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

pour GET / user?nom = bob

 var name = event.params.querystring.name;

cela ne résout pas la question GET user/bob.

2
répondu Michael Riecken 2016-06-13 01:57:41

Vous pouvez utilisé Lambda "Lambda Proxy" d'Intégration ,réf cet [ 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 avalible pour cette lambda sont

Pour Nodejs Lambda 'événement.les en-têtes', 'événement.pathParameters', ' event.corps", " événement.stageVariables", et l'événement.requestContext'

Pour Python Lambda événement['headers']['parametername'] et ainsi de suite

0
répondu RajDev 2018-01-09 18:06:30

après avoir lu plusieurs de ces réponses, j'ai utilisé une combinaison de plusieurs en août 2018 pour récupérer les params de chaîne de requête via lambda pour python 3.6.

tout d'abord, je suis allé à API Gateway -> My API -> resources (à gauche) -> Integration Request. En bas de la page, sélectionnez Modèles de mappage, puis entrez application/json pour le type de contenu .

ensuite, sélectionnez le modèle de transmission de requête de méthode fourni par Amazon et sélectionnez Enregistrer et déployez votre API.

puis dans, lambda event['params'] est la façon dont vous accédez à tous vos paramètres. Pour la chaîne de requête: event['params']['querystring']

0
répondu Jghorton14 2018-08-14 17:55:28

comme la réponse de @Jonathan, après la marque utilisez Lambda Proxy integration dans demande D'intégration , dans votre code source vous devez mettre en œuvre comme ci-dessous le format de By pass 502 Bad Gateway erreur.

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 relancer votre API. Réponse JSON just le retour qui est défini dans corps est correct. Ainsi, vous pouvez obtenir le chemin, le paramètre, les en-têtes, la valeur du corps de l'événement

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

0
répondu Long Nguyen 2018-08-31 01:38:13

la fonction Lambda attend l'entrée JSON, donc l'analyse de la chaîne de requête est nécessaire. La solution est de changer la chaîne de requête en JSON en utilisant le modèle de Mapping.

Je l'ai utilisé pour C# .NET Core, donc l'entrée attendue devrait être un JSON avec le paramètre "queryStringParameters".

suivre les 4 étapes ci-dessous pour atteindre cet objectif:

  1. ouvrez le modèle de mapping de votre ressource API Gateway et ajoutez une nouvelle 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 cartographie:

    {
    "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 mapping devrait créer la sortie JSON ci-dessous, qui est la entrée pour votre fonction Lambda.

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. C'est fini. À partir de ce point, la logique de votre fonction Lambda peut utiliser les paramètres de la chaîne de requête.

    Bonne chance!

0
répondu Lior Kirshner 2018-09-22 21:09:34

si vous utilisez JAVA pour vos fonctions Lambda, vous pouvez utiliser Lambada Framework qui prend soin de ce genre de choses pour vous.

-1
répondu Çağatay Gürtürk 2016-03-31 21:47:08