amazon web services - custom - Cómo pasar un parámetro de POST a AWS Lambda desde Amazon API Gateway
aws api (7)
Buena respuesta por r7kamura. Además, aquí hay un ejemplo de una plantilla de asignación comprensible y sólida para application/x-www-form-urlencoded
que funciona para todos los casos (asumiendo 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
}
}
Transformaría una entrada de
name=Marcus&email=email%40example.com&message=
dentro
{
"data": {
"name": "Marcus",
"email": "[email protected]",
"message": ""
}
}
Un controlador Lambda podría usarlo así (este devuelve todos los datos de entrada):
module.exports.handler = function(event, context, cb) {
return cb(null, {
data: event.data
});
};
En esta pregunta Cómo pasar un parámetro de cadena de consulta o ruta a AWS Lambda desde Amazon API Gateway
muestra cómo mapear los parámetros de cadena de consulta a AWS lambda utilizando la puerta de enlace API. Me gustaría hacer lo mismo, pero mapear valores POST en lugar de query-string. Lo intenté:
{
"values": "$input.params()"
}
pero no funcionó, no veo los datos del formulario real. Por cierto, estoy publicando usando:
application/x-www-form-urlencoded
Obtuve mi respuesta de mi función lambda, así que sé que está invocando lambda bien, pero mi problema es que no veo los parámetros POST en ninguna parte. No puedo resolver cómo mapearlos. Echo todo lo que tengo al lado de Lambda y aquí está:
{"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}}"}
Encontré una solución realmente simple, creo que vale la pena compartirla, ya que me tomó un tiempo encontrar este código de trabajo mínimo.
Si tiene un formulario común, que envía datos con el tipo de contenido application / x-www-form-urlencoded, simplemente marque "Integración del proxy Lambda", luego encontrará los datos del formulario codificado en event.body que se puede analizar con Node.js módulo nativo querystring.
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.
}
Esto funciona con la integración lambda. Suponiendo que su cuerpo de solicitud POST es, por ejemplo
{
"name" : "Hello",
"address" : "Cool place"
}
Puede acceder de esta manera:
if (event.body !== null && event.body !== undefined) {
let body = JSON.parse(event.body)
let name = body.name;
let address = body.address;
}
Más información aquí: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
Implementé una API con solicitudes POST donde Content-Type
fue application/x-www-form-urlencoded
. Si solo está interesado en obtener una cadena de consulta larga de valores similares a las solicitudes GET, utilice esta sintaxis de mapeo.
{
"body": "$input.body"
}
Tenga en cuenta que también puede agregar otras asignaciones ... Lo dejé para resolver el problema original.
Aquí hay un tutorial de blog que utilicé al implementar originalmente mi API. Mi función lambda luego analiza la cadena de consulta pasa los datos a otros procesos.
Puede convertir los datos de cualquier cuerpo de solicitud en formato JSON válido configurando las plantillas de asignación en la configuración de integración para que AWS Lambda pueda recibirla.
Actualmente parece que Amazon API Gateway aún no es compatible con application / x-www-form-urlencoded, pero avilewin publicó una solución para hacerlo en los foros de AWS. En las plantillas de asignación, puede usar Velocity Template Language (VTL) , por lo que lo que debe hacer es configurar las plantillas de asignación que conviertan el formato application / x-www-form-urlencoded en formato JSON válido. Por supuesto, esta es una solución sucia, pero creo que es la única manera de hacerlo por el momento.
Puede convertir los parámetros en JSON con una plantilla de puerta de enlace API: https://forums.aws.amazon.com/thread.jspa?messageID=673012&tstart=0#673012
O puede hacer esto en la función lambda utilizando el pacakge del analizador QueryString: https://www.npmjs.com/package/qs
var qs = require(''qs'');
var obj = qs.parse(''a=c''); // { a: ''c'' }
Si Amazon agrega compatibilidad integrada para dicha función, la usaré pero hasta ese momento yo personalmente prefiero la segunda porque es más limpia y más fácil de depurar si algo sale mal.
Actualización de julio de 2017 :
Puede utilizar la integración de proxy que lo admite de manera predeterminada: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
Si habilita la Integración de Proxy Lambda
El cuerpo POST estará disponible desde:
event[''body''][''param'']
Los parámetros y encabezados GET también estarán disponibles a través de
event[''pathParameters''][''param1'']
event["queryStringParameters"][''queryparam1'']
event[''requestContext''][''identity''][''userAgent'']
event[''requestContext''][''identity''][''sourceIP'']