it-swarm.com.de

Wie man ein Params von POST AWS Lambda von Amazon API Gateway

In dieser Frage So übergeben Sie einen Parameter für eine Querzeichenfolge oder eine Route von Amazon API Gateway an AWS Lambda

zeigt, wie Abfragezeichenfolgenparameter mithilfe von API-Gateway zu AWS-Lambda zugeordnet werden. Ich möchte dasselbe tun, aber POST Werte anstelle von Abfragezeichenfolge zuordnen. Ich habe es versucht:

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

hat aber nicht funktioniert, ich sehe nicht die eigentlichen Formulardaten. Übrigens poste ich mit: 

application/x-www-form-urlencoded

Ich bekomme meine Antwort von meiner Lambda-Funktion, also weiß ich, dass es gut ist, aber es ist mein Problem, dass ich die POST -Parameter nirgendwo sehe. Ich kann nicht herausfinden, wie ich sie abbilden kann. Ich lasse alles auf Lambda-Seite fallen und hier ist es:

 {"values":"{path={}, querystring={}, header={Accept=*/*, Accept-Encoding=gzip, deflate, Accept-Language=en-US,en;q=0.8, Cache-Control=no-cache, CloudFront-Forwarded-Proto=https, CloudFront-Is-Desktop-Viewer=true, CloudFront-Is-Mobile-Viewer=false, CloudFront-Is-SmartTV-Viewer=false, CloudFront-Is-Tablet-Viewer=false, CloudFront-Viewer-Country=US, Content-Type=application/x-www-form-urlencoded, Origin=chrome-extension://fhbjgbiflinjbdggehcddcbncdddomop, Postman-Token=7ba28698-8753-fcb1-1f48-66750ce12ade, Via=1.1 6ba5553fa41dafcdc0e74d152f3a7a75.cloudfront.net (CloudFront), X-Amz-Cf-Id=sc8C7dLcW0BHYopztNYrnddC0hXyFdBzHv0O9aWU1gKhd1D_J2HF3w==, X-Forwarded-For=50.196.93.57, 54.239.140.62, X-Forwarded-Port=443, X-Forwarded-Proto=https}}"}
34
ecorvo

Gute Antwort von r7kamura. Zusätzlich ist hier ein Beispiel einer verständlichen und robusten Zuordnungsvorlage für application/x-www-form-urlencoded, die für alle Fälle funktioniert (vorausgesetzt, POST):

{
    "data": {
        #foreach( $token in $input.path('$').split('&') )
            #set( $keyVal = $token.split('=') )
            #set( $keyValSize = $keyVal.size() )
            #if( $keyValSize >= 1 )
                #set( $key = $util.urlDecode($keyVal[0]) )
                #if( $keyValSize >= 2 )
                    #set( $val = $util.urlDecode($keyVal[1]) )
                #else
                    #set( $val = '' )
                #end
                "$key": "$val"#if($foreach.hasNext),#end
            #end
        #end
    }
}

Es würde eine Eingabe von

name=Marcus&email=email%40example.com&message=

in

{
    "data": {
                "name": "Marcus",
                "email": "[email protected]",
                "message": ""
    }
}

Ein Lambda-Handler könnte es so verwenden (dieser gibt alle Eingabedaten zurück):

module.exports.handler = function(event, context, cb) {
  return cb(null, {
    data: event.data
  });
};
54
Marcus Whybrow

Sie können alle Anforderungshauptdaten in ein gültiges JSON-Format konvertieren, indem Sie die Zuordnungsvorlagen in den Integrationseinstellungen so konfigurieren, dass AWS Lambda sie erhalten kann.

Derzeit scheint Amazon API Gateway offiziell noch nicht application/x-www-form-urlencoded zu unterstützen, aber avilewin hat eine Lösung geschrieben, um dies in den AWS-Foren zu tun. In den Zuordnungsvorlagen können Sie Velocity Template Language (VTL) verwenden. Sie müssen also Zuordnungsvorlagen konfigurieren, die das Format application/x-www-form-urlencoded in ein gültiges JSON-Format konvertieren. Natürlich ist dies eine schmutzige Lösung, aber ich denke, es ist der einzige Weg, das für den Moment zu tun.

20
r7kamura

Wenn Sie die Lambda-Proxy-Integration aktivieren  enter image description here

Der POST Body wird verfügbar sein von:

event['body']['param']

GET-Parameter und -Header sind ebenfalls über verfügbar

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

Sie können die Parameter mit einer API-Gateway-Vorlage in JSON konvertieren: https://forums.aws.Amazon.com/thread.jspa?messageID=673012&tstart=0#673012

Oder Sie können dies in der Lambda-Funktion selbst mit QueryString-Parser-Paket ausführen: https://www.npmjs.com/package/qs

var qs = require('qs');
var obj = qs.parse('a=c');  // { a: 'c' } 

Wenn Amazon eine integrierte Unterstützung für eine solche Funktion hinzufügt, werde ich diese Funktion verwenden. Bis dahin bevorzuge ich persönlich die zweite Möglichkeit, da sie sauberer und einfacher zu debuggen ist, wenn etwas schief geht.

Update Juli 2017:

Sie können die Proxy-Integration verwenden, die dies standardmäßig unterstützt: http://docs.aws.Amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for- lambda.html

11
advncd

@ Markus-whybrow Antwort erweitern:

{
        #foreach( $token in $input.path('$').split('&') )
            #set( $keyVal = $token.split('=') )
            #set( $keyValSize = $keyVal.size() )
            #if( $keyValSize >= 1 )
                #set( $key = $util.urlDecode($keyVal[0]) )
                #if( $keyValSize >= 2 )
                    #set( $val = $util.urlDecode($keyVal[1]) )
                #else
                    #set( $val = '' )
                #end
                "$key": "$util.escapeJavaScript($val)"#if($foreach.hasNext),#end
            #end
        #end
    }

Dies entfernt "Daten" und behebt auch einen Fall, wenn in einem Ihrer Werte ein Anführungszeichen steht.

3
Mark Sergienko

Ich habe eine API mit POST - Anforderungen implementiert, bei denen Content-Typeapplication/x-www-form-urlencoded war. Wenn Sie nur an einer langen Abfrage von Werten interessiert sind, die den GET-Anforderungen ähneln, verwenden Sie diese Mapping-Syntax.

{
    "body": "$input.body"
}

Beachten Sie, Sie können auch andere Zuordnungen hinzufügen ... Ich habe das ausgelassen, um das ursprüngliche Problem zu lösen.

Hier ist ein Blog-Tutorial, das ich bei der ursprünglichen Implementierung meiner API verwendet habe. Meine Lambda-Funktion analysiert dann den Querystring, der die Daten an andere Prozesse weiterleitet. 

2
openwonk

Ich habe eine wirklich einfache Lösung gefunden, von der ich denke, dass sie es wert ist, sie weiterzugeben, da ich einige Zeit brauchte, um diesen minimalen Arbeitscode zu finden.

Wenn Sie ein allgemeines Formular haben, das Daten mit dem Inhaltstyp application/x-www-form-urlencoded sendet, markieren Sie einfach "Lambda-Proxy-Integration". Dann finden Sie in event.body codierte Formulardaten, die mit Node.js analysiert werden können Abfragen des nativen Moduls.

const querystring = require('querystring')

function handler (event, context, callback) {
  // Read form data.
  const { user, pass } = querystring.parse(event.body)

  // Follows your code to handle request.
}
1
Gianluca Casati

Einfache Funktion, die ein geordnetes Wörterbuch mit gebuchten Werten zurückgibt:

import urllib
from collections import OrderedDict
postdata = ''

def GetPostData(body):
    #postdata = OrderedDict()
    postdata = {}
    for items in body.split('&'):
        vals = items.split('=')
        postdata[vals[0]] = urllib.parse.unquote(vals[1])
    return postdata

#Testing it out:
#Assume you get body from event['body'] or body = event.get['body']
body = 'text=This%20works%20really%20well%21%245123%21%403%2146t5%40%2341&anotherkey=isawesome23412%201%21%403%21%40312'

postdata = GetPostData(body)
print(postdata['text'])
#returns 'This works really [email protected][email protected]#41'
print(postdata['anotherkey'])
#returns 'isawesome23412 [email protected][email protected]'

Um einen Schlüsselfehler zu vermeiden, wenn ein Beitrag fehlt, sollten Sie stattdessen value = postdata.get ('') verwenden, da der Wert None ist, wenn der Schlüssel nicht vorhanden ist.

0
Arvin Amir

Dies funktioniert mit der Lambda-Integration . Angenommen, Ihr POST - Request-Body ist z. 

{
   "name" : "Hello",
   "address" : "Cool place" 
}

Sie können wie folgt darauf zugreifen: 

if (event.body !== null && event.body !== undefined) {
   let body = JSON.parse(event.body)
   let name = body.name;
   let address = body.address;
}

Weitere Informationen hier: http://docs.aws.Amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html

0
Dodi

Wenn Sie den gesamten Körper vom POST an Ihre Lambda-Funktion senden möchten, schreiben Sie dies an Integration Request:

{
    "values": $input.json('$')
}

Wenn Sie eine eigene Struktur aus dem Körper erstellen möchten, gehen Sie wie folgt vor:

{
    "values": {
        "body-param1": $input.json('body-param1'),
        "others": {
            "body-param2": "$input.json('body-param2')",
        }
    }
}

Dabei ist body-param1 eine Zahl und body-param2 eine Zeichenfolge.

Wenn Sie die Header senden möchten, gehen Sie wie folgt vor:

{
    "headers": {
        #foreach($param in $input.params().header.keySet())
            "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext), #end
        #end
    }
}
0
Camilo Ortegón