So übergeben Sie einen Querystring- oder Routenparameter vom Amazon API Gateway an AWS Lambda

348

zum Beispiel, wenn wir verwenden wollen

GET /user?name=bob

oder

GET /user/bob

Wie würden Sie diese beiden Beispiele als Parameter an die Lambda-Funktion übergeben?

Ich habe in der Dokumentation etwas über das Festlegen einer "Zuordnung von" gesehen, kann diese Einstellung jedoch nicht in der API-Gateway-Konsole finden.

  • method.request.path.parameter-namefür einen Pfadparameter mit dem Namen, parameter-namewie auf der Seite Methodenanforderung definiert.
  • method.request.querystring.parameter-namefür einen Abfragezeichenfolgenparameter mit dem Namen, parameter-namewie auf der Seite Methodenanforderung definiert.

Ich sehe keine dieser Optionen, obwohl ich eine Abfragezeichenfolge definiert habe.

MonkeyBonkey
quelle

Antworten:

299

Ab September 2017 müssen Sie keine Zuordnungen mehr konfigurieren, um auf den Anforderungshauptteil zuzugreifen.

Sie müssen lediglich unter Integrationsanforderung unter der Ressource die Option "Lambda-Proxy-Integration verwenden" aktivieren.

Geben Sie hier die Bildbeschreibung ein

Sie können dann auf Abfrageparameter, Pfadparameter und solche Header zugreifen

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
Jonathan
quelle
23
Dies ist ein großartiger Tipp. Beachten Sie jedoch, dass das Aktivieren der Lambda-Proxy-Integration einen Fehler "Fehlerhafte Lambda-Proxy-Antwort" verursachen kann. So beheben Sie das Problem
AaronBaker
5
Gibt es eine Möglichkeit, dies in Java zu tun, während die transparente Deserialisierung, die die Implementierung RequestHandlerbietet, beibehalten wird?
Schuh
2
Wo ist diese Einstellung?
Red888
2
@MattWestlake Sie erstellen eine Ressource namens user und darunter eine Ressource namens {name} in API Gateway.
Jonathan
3
Ich möchte nur erwähnen, dass ich nach dieser Änderung auch zu Amazon API Gateway -> Aktionen -> API bereitstellen und erneut in der Live-Umgebung bereitstellen musste.
Victorvartan
221

Die Schritte, um dies zum Laufen zu bringen, sind:

Innerhalb der API Gateway Console ...

  1. gehe zu Resources -> Integration Request
  2. Klicken Sie auf das Plus- oder Bearbeitungssymbol neben dem Dropdown-Menü "Vorlagen" (seltsam, da das Vorlagenfeld bereits geöffnet ist und die Schaltfläche hier ausgegraut aussieht).
  3. application/jsonGeben Sie das Feld Inhaltstyp explizit ein , obwohl es eine Standardeinstellung anzeigt (wenn Sie dies nicht tun, wird es nicht gespeichert und es wird keine Fehlermeldung angezeigt).
  4. Fügen Sie dies in das Eingabe-Mapping ein { "name": "$input.params('name')" }

  5. Klicken Sie auf das Kontrollkästchen neben der Vorlagen-Dropdown-Liste (ich gehe davon aus, dass dies das ist, was es endgültig speichert).

MonkeyBonkey
quelle
9
Haben Sie dies jemals dazu gebracht, URL-Parameter in URLs wie / user / bob zu senden, in denen die Route / user / {Benutzername} war? Ich habe alle Arten von Permutationen ausprobiert, konnte das aber nicht herausfinden.
Lucas
5
Weiß jemand, ob es offizielle Unterlagen gibt? Es wäre schön, einfach alle Abfrageparameter zu durchlaufen oder optionale Werte
eleganter zu
6
Ein Tipp für iOS-Entwickler: API Gateway übergibt keine Abfragedaten, bis Sie jede Variable als Abfragezeichenfolge (unter 'Methodenanforderung') definieren UND API bereitstellen. Bis zur Bereitstellung funktioniert es vom Konsolentest aus, schneidet jedoch die Abfragen der App ab.
AlexeyVMP
6
Lucas, ich habe es mit dem Muster / user / {username} zum Laufen gebracht. Denken Sie daran, wenn Ihr GET-Ressourcenpfad / user / {Benutzername} lautet. In Schritt 4 sieht die Eingabezuordnung folgendermaßen aus: {"name": "$ input.params ('Benutzername')"}
Gerard
134

Ich habe diese Zuordnungsvorlage verwendet, um dem Lambda-Ereignis Parameter für Body, Header, Methode, Pfad und URL-Abfragezeichenfolge bereitzustellen. Ich habe einen Blog-Beitrag geschrieben, in dem die Vorlage ausführlicher erläutert wird: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api- Tor/

Hier ist die Zuordnungsvorlage, die Sie verwenden können:

{
  "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
  }  
}
kennbrodhagen
quelle
Tolle! Ich hatte Probleme damit, Dinge generisch an meinen Handler weiterzugeben. Beste Antwort hier.
Venkat D.
Ich habe das getan, aber ich bekomme noch nichts. Es zeigt Undefiniert. Wie sollen wir die Parameter in der URL senden? und müssen wir den Variablennamen in der URL angeben, wie in einem normalen GET-URL-Szenario? Bitte helfen Sie mir dabei.
Parthapratim Neog
8
Egal, ich habe das Ergebnis. Das Problem war, ich habe das Mapping hinzugefügt und es einfach gespeichert und deploydie API nicht noch einmal. Nachdem ich die API mit dem neuen Mapping bereitgestellt hatte, funktionierte es einwandfrei. Danke vielmals.
Parthapratim Neog
@ Shashu10 Siehe meine Antwort
Matsev
1
Ich kann Ihnen nicht sagen, wie nützlich Ihr Blog ist. Ich habe zuerst den Beitrag "eturn-html-from-aws-api-gateway" gefunden und bin ihm gefolgt, weil er genau das ist, was ich brauchte. Jetzt muss ich einige Parameter an die Funktion übergeben und das HTML darauf basierend ändern - und wieder sind Sie der einzige mit einer echten Anleitung! Alle anderen Führer, die ich gefunden habe, scheinen den Punkt zu verfehlen.
user3685427
41

Heutzutage ist eine Dropdown-Vorlage in der API Gateway Console unter AWS enthalten.

Klicken Sie für Ihre API auf den Ressourcennamen ... und dann auf GET

Erweitern Sie "Body Mapping-Vorlagen".

Eintippen

Anwendung / json

für Content-Type (muss explizit eingegeben werden) und klicken Sie auf das Häkchen

Ein neues Fenster mit den Worten "Vorlage erstellen" und einem Dropdown-Menü (siehe Bild) wird geöffnet.

Wählen

Passthrough für Methodenanforderung

Geben Sie hier die Bildbeschreibung ein

Klicken Sie dann auf Speichern

Um auf Variablen zuzugreifen, verwenden Sie einfach die folgende Syntax (dies ist Python), z. B. URL:

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

Sie können Variablen wie folgt abrufen:

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'])

Es ist also nicht erforderlich, jede gewünschte Variable explizit zu benennen oder zuzuordnen.

Dirk Conrad Coetsee
quelle
Ausgezeichnet! Die Funktionalität ist genau dort im Service, hatte es aber verpasst!
Hnvasa
25

Um Parameter an Ihre Lambda-Funktion zu übergeben, müssen Sie eine Zuordnung zwischen der API-Gateway-Anforderung und Ihrer Lambda-Funktion erstellen. Die Zuordnung erfolgt im Abschnitt Integration Request-> Mapping templatesder ausgewählten API-Gateway-Ressource.

Erstellen Sie eine Typzuordnung application/json, und bearbeiten Sie rechts die Vorlage (klicken Sie auf den Stift).

Eine Mapping-Vorlage ist eigentlich eine Velocity-Vorlage, in der Sie ifs, Schleifen und natürlich Druckvariablen verwenden können. In die Vorlage werden diese Variablen eingefügt, über die Sie einzeln auf Querystring-Parameter, Anforderungsheader usw. zugreifen können. Mit dem folgenden Code können Sie den gesamten Querystring neu erstellen:

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

Hinweis: Klicken Sie auf das Häkchensymbol, um die Vorlage zu speichern. Sie können Ihre Änderungen mit der Schaltfläche "Test" in Ihrer Ressource testen. Um jedoch Querystring-Parameter in der AWS-Konsole zu testen, müssen Sie die Parameternamen im Method RequestAbschnitt Ihrer Ressource definieren.

Hinweis: Weitere Informationen zur Velocity-Vorlagensprache finden Sie im Velocity-Benutzerhandbuch .

Dann können Sie in Ihrer Lambda-Vorlage Folgendes tun, um den Querystring zu analysieren:

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
gimenete
quelle
9
Dies ist die beste Lösung. Bitte denken Sie daran Actions>Deploy API(ich habe meine Zeit damit verschwendet, dies zu vergessen ...). Der zugehörige Lambda-Arn übernimmt die Änderung unmittelbar nach der Bereitstellung. Sie können es einchecken Stages > #stage (like: prod) > Deployment History.
Loretoparisi
24

Die akzeptierte Antwort funktionierte gut für mich, aber als Erweiterung der Antwort von gimenete wollte ich eine generische Vorlage, mit der ich alle Abfrage- / Pfad- / Header-Parameter (vorerst nur als Zeichenfolgen) durchlaufen konnte, und ich kam auf die folgende Vorlage. Ich poste es hier, falls jemand es nützlich findet:

#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
}
BenV
quelle
1
Fab, ich wollte in der Lage sein, die gleiche Funktion sowohl für POST-Anforderungen (mit JSON-Body) als auch für GET mit Abfragezeichenfolgen zu verwenden. Arbeitet einen Traum. Vielen Dank!
Matt Fletcher
@benv ist das die vollständige Vorlage?
Nxmohamad
17

Als ich versuchte, eine meiner eigenen Fragen hier zu beantworten , stieß ich auf diesen Trick.

Verwenden Sie in der API-Gateway-Zuordnungsvorlage Folgendes, um die vollständige Abfragezeichenfolge anzugeben, die vom HTTP-Client gesendet wurde:

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

Der Vorteil ist, dass Sie sich nicht auf einen Satz vordefinierter zugeordneter Schlüssel in Ihrer Abfragezeichenfolge beschränken müssen. Jetzt können Sie alle Schlüssel-Wert-Paare in der Abfragezeichenfolge akzeptieren, wenn Sie dies so behandeln möchten.

Hinweis: Nach dieser , nur $input.params(x)aufgeführt wird als eine Variable für die VTL - Vorlage zur Verfügung gestellt. Es ist möglich, dass sich die Interna ändern und querystringnicht mehr verfügbar sind.

user3526
quelle
1
Dies funktioniert noch ab Mai 2017, gibt jedoch das JS-Objekt zurück, das API Gateway für Sie erstellt, und nicht die eigentliche Abfragezeichenfolge. Dies ist für mich ärgerlich, da ich versuche, die Abfragezeichenfolge zu analysieren, um wiederholte Parameter in ein Array umzuwandeln.
Tom Saleeba
11

Jetzt sollten Sie in der Lage sein, den neuen Proxy-Integrationstyp für Lambda zu verwenden, um automatisch die vollständige Anforderung in Standardform zu erhalten, anstatt Zuordnungen zu konfigurieren.

Siehe: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on- Proxy-Ressource

Jack Kohn - AWS
quelle
1
Ich bin mir nicht sicher warum, aber die Proxy-Integration funktioniert normalerweise nicht für mich. Ich musste es aus den neuesten APIs entfernen, die ich erstellt habe.
Gustavo Straube
Ich hatte außerdem CORS-Probleme mit API Gateway. Zusammen mit AWS-Dokumenten konnte ich CORS nicht zum Laufen bringen. Ich fand jedoch einen alten Medium-Artikel von Mitte bis Ende 2015, der eine manuelle Methode zum Einrichten von CORS hatte und der funktionierte.
Stephen Tetreault
7

GET / user? Name = bob

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

GET / user / bob

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

Viele der Antworten hier sind großartig. Aber ich wollte etwas einfacheres. Ich wollte etwas, das mit dem "Hello World" -Beispiel kostenlos funktioniert. Dies bedeutet, dass ich wollte, dass ein einfacher einen Anforderungshauptteil erzeugt, der mit der Abfragezeichenfolge übereinstimmt:

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

Ich denke, die Top-Antwort bringt etwas Nützlicheres hervor, wenn Sie etwas Reales erstellen, aber um mit der Vorlage von AWS eine schnelle Hallo-Welt zum Laufen zu bringen, funktioniert dies hervorragend.

KrisTC
quelle
4

Das folgende Beispiel für die Parameterzuordnung übergibt alle Parameter, einschließlich Pfad, Querystring und Header, über eine JSON-Nutzlast an den Integrationsendpunkt

#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
  }
}

Tatsächlich gibt diese Zuordnungsvorlage alle Anforderungsparameter in der Nutzlast wie folgt aus:

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

Kopiert aus dem Amazon API Gateway Developer Guide

matsev
quelle
2

Die Abfragezeichenfolge ist einfach zu analysieren in Javascript im Lambda

für GET / user? name = bob

 var name = event.params.querystring.name;

Dies löst jedoch nicht die GET-Benutzer- / Bob-Frage.

Michael Riecken
quelle
seine event.queryStringParameters.name
Neo
Ich musste tunevent.queryStringParameters.name
Anders Kitson
2

Als Antwort von @ Jonathan sollten Sie nach dem Markieren Verwenden der Lambda-Proxy-Integration in der Integrationsanforderung in Ihrem Quellcode das folgende Format implementieren, um den Fehler 502 Bad Gateway zu umgehen.

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;
};

Vergessen Sie nicht, Ihre Ressource bei API Gateway bereitzustellen, bevor Sie Ihre API erneut ausführen. Antwort JSON gibt nur zurück, welcher Satz in body korrekt ist. Sie können also Pfad, Parameter, Header und Body-Wert vom Ereignis abrufen

const {path, queryStringParameters, headers, body} = event;

Langer Nguyen
quelle
1

Die Lambda-Funktion erwartet eine JSON-Eingabe, daher ist das Parsen der Abfragezeichenfolge erforderlich. Die Lösung besteht darin, die Abfragezeichenfolge mithilfe der Zuordnungsvorlage in JSON zu ändern.
Ich habe es für C # .NET Core verwendet, daher sollte die erwartete Eingabe ein JSON mit dem Parameter "queryStringParameters" sein.
Befolgen Sie diese 4 Schritte, um dies zu erreichen:

  1. Öffnen Sie die Zuordnungsvorlage Ihrer API-Gateway-Ressource und fügen Sie neue application/jsonInhalte hinzu:

API-Gateway-Zuordnungsvorlage

  1. Kopieren Sie die folgende Vorlage, die die Abfragezeichenfolge in JSON analysiert, und fügen Sie sie in die Zuordnungsvorlage ein:

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. Rufen Sie im API-Gateway Ihre Lambda-Funktion auf und fügen Sie die folgende Abfragezeichenfolge hinzu (für das Beispiel): param1=111&param2=222&param3=333

  3. Die Zuordnungsvorlage sollte die folgende JSON-Ausgabe erstellen, die die Eingabe für Ihre Lambda-Funktion ist.

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. Du bist fertig. Ab diesem Punkt kann die Logik Ihrer Lambda-Funktion die Abfragezeichenfolgenparameter verwenden.
    Viel Glück!

Lior Kirshner
quelle
0

Sie können Lambda als "Lambda-Proxy-Integration" verwenden . Siehe hierzu [ https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda. html # api-gateway-proxy-integration-lambda-funktion-python] , Optionen, die für dieses Lambda verfügbar sind, sind

Für Nodejs Lambda 'event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables' und 'event.requestContext'

Für Python Lambda-Ereignis ['Header'] ['Parametername'] und so weiter

RajDev
quelle
-1

Nachdem ich einige dieser Antworten gelesen hatte, verwendete ich im August 2018 eine Kombination aus mehreren, um die Abfragezeichenfolgenparameter über Lambda für Python 3.6 abzurufen.

Zuerst ging ich zu API Gateway -> Meine API -> Ressourcen (links) -> Integrationsanforderung. Wählen Sie unten Mapping Templates aus und geben Sie als Inhaltstyp ein application/json.

Wählen Sie als Nächstes die von Amazon bereitgestellte Vorlage für die Anforderung von Passthrough für Methoden an und wählen Sie Speichern und Bereitstellen Ihrer API aus.

In Lambda event['params']greifen Sie dann auf alle Ihre Parameter zu. Für Abfragezeichenfolge:event['params']['querystring']

Jghorton14
quelle