Como passar um parâmetro de string ou rota de consulta para o AWS Lambda no Amazon API Gateway

348

por exemplo, se queremos usar

GET /user?name=bob

ou

GET /user/bob

Como você passaria esses dois exemplos como parâmetro para a função Lambda?

Vi algo sobre como definir um "mapeado de" na documentação, mas não consigo encontrá-la no console do API Gateway.

  • method.request.path.parameter-namepara um parâmetro de caminho chamado parameter-nameconforme definido na página Solicitação de Método.
  • method.request.querystring.parameter-namepara um parâmetro de cadeia de consulta nomeado parameter-nameconforme definido na página Solicitação de Método.

Não vejo nenhuma dessas opções, embora tenha definido uma sequência de consultas.

MonkeyBonkey
fonte

Respostas:

299

Desde setembro de 2017, você não precisa mais configurar mapeamentos para acessar o corpo da solicitação.

Tudo o que você precisa fazer é verificar "Usar a integração do Proxy Lambda", em Solicitação de integração, no recurso.

insira a descrição da imagem aqui

Você poderá acessar parâmetros de consulta, parâmetros de caminho e cabeçalhos como este

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
Jonathan
fonte
23
Esta é uma ótima dica. Porém, lembre-se de que ativar a integração do proxy lambda pode causar um erro "Resposta do proxy lambda malformado". Veja como corrigi-lo: stackoverflow.com/questions/43708017/…
AaronBaker
5
existe uma maneira de fazer isso em java, mantendo a desserialização transparente que a implementação RequestHandlerfornece?
shoe
2
onde esta configuração?
red888
2
@MattWestlake Você cria um recurso chamado user e, sob ele, um recurso chamado {name} no API Gateway.
22718 Jonathan
3
Eu só quero mencionar que, após essa alteração, também tive que ir para o Amazon API Gateway -> Ações -> Implementar API e reimplementar no ambiente ativo.
Victorvartan 9/08
221

As etapas para fazer isso funcionar são:

No console do API Gateway ...

  1. vamos para Resources -> Integration Request
  2. clique no ícone de adição ou edição ao lado do menu suspenso de modelos (estranho, eu sei que o campo do modelo já está aberto e o botão aqui parece acinzentado)
  3. Digite explicitamente application/jsono campo do tipo de conteúdo, mesmo que mostre um padrão (se você não fizer isso, ele não será salvo e não será exibida uma mensagem de erro)
  4. coloque isso no mapeamento de entrada { "name": "$input.params('name')" }

  5. clique na caixa de seleção ao lado do menu suspenso de modelos (suponho que é isso que finalmente o salva)

MonkeyBonkey
fonte
9
Você já conseguiu isso enviar parâmetros de URL em URLs como / user / bob onde a rota era / user / {nomedeusuário}? Eu tentei todos os tipos de permutações, mas não consegui resolver isso.
Lucas
5
alguém sabe se existe alguma documentação oficial? seria bom apenas para passar por todos os parâmetros de consulta ou lidar com valores opcionais mais graciosa do que strings vazias
AxelTheGerman
6
Uma dica para desenvolvedores do iOS: o API Gateway não passará os dados da consulta até que você defina cada variável como uma string de consulta (em 'Solicitação de método') E implemente a API. Até a implantação, ele funciona a partir do teste do console, mas corta as consultas do aplicativo.
AlexeyVMP
6
Lucas, consegui funcionar usando o padrão / user / {nome de usuário}. Lembre-se de que se o caminho do seu recurso GET for / user / {nomedeusuário}, na etapa 4 o mapeamento de entrada se parecerá com este {"name": "$ input.params ('nomedeusuário')"}
Gerard
134

Eu usei esse modelo de mapeamento para fornecer parâmetros de String de consulta de corpo, cabeçalhos, método, caminho e URL para o evento Lambda. Eu escrevi uma postagem no blog explicando o modelo em mais detalhes: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api- Porta de entrada/

Aqui está o modelo de mapeamento que você pode usar:

{
  "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
fonte
Surpreendente! Eu estava lutando para transmitir as coisas genericamente ao meu manipulador. Melhor resposta aqui.
Venkat D.
Eu fiz isso, mas ainda não estou conseguindo nada. Está mostrando indefinido. Como devemos enviar os parâmetros na URL? e precisamos especificar o nome da variável no URL, como em um cenário normal de URL GET? Por favor me ajude com isso.
você precisa saber é o seguinte
8
Não importa, eu consegui o resultado. O problema era que eu adicionei o mapeamento e apenas o salvei, e não fiz deploya API novamente. Depois que implantei a API com o novo mapeamento, ele funcionou bem. Muito obrigado.
você precisa saber é o seguinte
@ shashu10 Veja minha resposta
matsev
11
Não posso começar a dizer o quão útil é o seu blog. Encontrei o post "eturn-html-from-aws-api-gateway" primeiro e o segui, porque é exatamente o que eu precisava. Agora eu preciso passar alguns parâmetros para a função e modificar o html com base nisso - e novamente você é o único com um guia real! Todos os outros guias que encontrei parecem errar o ponto.
user3685427
41

Atualmente, um modelo suspenso é incluído no API Gateway Console na AWS.

Para sua API, clique no nome do recurso ... e depois em GET

Expandir "Modelos de mapeamento do corpo"

Digitar

application / json

para Content-Type (deve ser digitado explicitamente) e clique no visto

Uma nova janela será aberta com as palavras "Gerar modelo" e uma lista suspensa (veja a imagem).

Selecione

Passagem de Solicitação de Método

insira a descrição da imagem aqui

Depois clique em salvar

Para acessar qualquer variável, basta usar a seguinte sintaxe (esta é Python), por exemplo, URL:

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

Você pode obter variáveis ​​da seguinte maneira:

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

Portanto, não há necessidade de nomear ou mapear explicitamente cada variável que você deseja.

Dirk Conrad Coetsee
fonte
excelente! a funcionalidade está ali no serviço, mas havia perdido!
hnvasa
25

Para passar parâmetros para sua função lambda, você precisa criar um mapeamento entre a solicitação do API Gateway e sua função lambda. O mapeamento é feito na seção Integration Request-> Mapping templatesdo recurso API Gateway selecionado.

Crie um mapeamento do tipo e application/json, à direita, edite (clique no lápis) o modelo.

Um modelo de mapeamento é na verdade um modelo Velocity, no qual você pode usar ifs, loops e, é claro, imprimir variáveis ​​nele. O modelo tem essas variáveis ​​injetadas, onde você pode acessar os parâmetros da string de consulta, solicitar cabeçalhos, etc. individualmente. Com o código a seguir, você pode recriar toda a string de consulta:

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

Nota: clique no símbolo de verificação para salvar o modelo. Você pode testar suas alterações com o botão "test" no seu recurso. Mas, para testar os parâmetros da string de consulta no console da AWS, você precisará definir os nomes dos parâmetros na Method Requestseção do seu recurso.

Nota: consulte o Guia do usuário do Velocity para obter mais informações sobre o idioma do modelo de velocidade.

Em seu modelo lambda, você pode fazer o seguinte para obter a string de consulta analisada:

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
gimenete
fonte
9
essa é a melhor solução. Por favor, lembre-se de fazê Actions>Deploy API-lo (perdi meu tempo esquecendo isso ...). O lambda arn associado fará a alteração imediatamente após a implantação. Você pode fazer o check-in Stages > #stage (like: prod) > Deployment History.
Loretoparisi
24

A resposta aceita funcionou bem para mim, mas, expandindo a resposta de gimenete, eu queria um modelo genérico que pudesse usar para passar por todos os parâmetros de consulta / caminho / cabeçalho (assim como cadeias de caracteres por enquanto) e criei o modelo a seguir. Estou postando aqui caso alguém ache útil:

#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
fonte
11
Fab, eu queria poder usar a mesma função para solicitações POST (com corpo JSON) e GET com cadeias de consulta. Realiza um sonho. Obrigado!
Matt Fletcher
@ Benv este é o modelo completo?
Nxmohamad 13/05/19
17

Como parte da tentativa de responder uma de minhas próprias perguntas aqui , me deparei com esse truque.

No modelo de mapeamento do API Gateway, use o seguinte para fornecer a sequência de consultas completa conforme enviada pelo cliente HTTP:

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

A vantagem é que você não precisa se limitar a um conjunto de chaves mapeadas predefinidas na sua string de consulta. Agora você pode aceitar quaisquer pares de valores-chave na cadeia de caracteres de consulta, se é assim que deseja lidar.

Nota: De acordo com isso , apenas $input.params(x)é listado como uma variável disponibilizada para o modelo VTL. É possível que os internos possam mudar e querystringnão estejam mais disponíveis.

user3526
fonte
11
Isso ainda funciona a partir de maio de 2017, mas retorna o objeto JS que o API Gateway cria para você, em vez da string de consulta real. Isso é chato para mim, porque estou tentando analisar a string de consulta para transformar parâmetros repetidos em uma matriz.
Tom Saleeba
11

Agora você deve poder usar o novo tipo de integração de proxy do Lambda para obter automaticamente a solicitação completa no formato padrão, em vez de configurar os mapeamentos.

consulte: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on- recurso de proxy

Jack Kohn - AWS
fonte
11
Não sei por que, mas a integração de proxy geralmente não funciona para mim. Eu tive que removê-lo das últimas APIs que eu criei.
Gustavo Straube 27/09
mesmo ^ além disso, tive problemas com o CORS com o API Gateway. Seguindo os documentos da AWS, não consegui fazer o CORS funcionar. No entanto, encontrei um artigo antigo do Medium de meados do final de 2015 que tinha uma maneira manual de configurar o CORS e que funcionava.
Stephen Tetreault
7

GET / usuário? Nome = bob

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

GET / usuário / bob

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

Muitas das respostas aqui são ótimas. Mas eu queria algo um pouco mais simples. Eu queria algo que funcionasse de graça com a amostra "Hello World". Isso significa que eu queria que um simples produz um corpo de solicitação que corresponda à string de consulta:

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

Acho que a resposta principal produz algo mais útil ao criar algo real, mas para obter um mundo rápido de olá usando o modelo da AWS, isso funciona muito bem.

KrisTC
fonte
4

O exemplo de mapeamento de parâmetro a seguir transmite todos os parâmetros, incluindo caminho, string de consulta e cabeçalho, para o terminal de integração por meio de uma carga 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
  }
}

Com efeito, este modelo de mapeamento gera todos os parâmetros de solicitação na carga útil, conforme descrito a seguir:

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

Copiado do Amazon API Gateway Developer Guide

Matsev
fonte
2

A string de consulta é simples para analisar em javascript no lambda

para GET / usuário? name = bob

 var name = event.params.querystring.name;

Isso não resolve a questão do usuário / bobina GET.

Michael Riecken
fonte
sua event.queryStringParameters.name
Neo
Eu tive que fazerevent.queryStringParameters.name
Anders Kitson
2

Como resposta de @ Jonathan, após a marca Use a integração do Proxy Lambda na solicitação de integração , em seu código-fonte você deve implementar o formato abaixo para passar o erro 502 Bad Gateway .

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ão se esqueça de implantar seu recurso no API Gateway antes de executar novamente sua API. Resposta JSON apenas retorna qual conjunto no corpo está correto. Assim, você pode obter caminho, parâmetro, cabeçalhos, valor do corpo do evento

const {caminho, queryStringParameters, cabeçalhos, corpo} = evento;

Long Nguyen
fonte
1

A função Lambda espera entrada JSON, portanto, é necessário analisar a cadeia de consulta. A solução é alterar a cadeia de consulta para JSON usando o Modelo de Mapeamento.
Eu o usei no C # .NET Core, portanto, a entrada esperada deve ser um JSON com o parâmetro "queryStringParameters".
Siga estas 4 etapas abaixo para conseguir isso:

  1. Abra o modelo de mapeamento do seu recurso API Gateway e adicione um novo tipo de application/jsonconteúdo:

Modelo de mapeamento do API Gateway

  1. Copie o modelo abaixo, que analisa a string de consulta em JSON e cole-a no modelo de mapeamento:

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. No API Gateway, chame sua função Lambda e adicione a seguinte string de consulta (por exemplo): param1=111&param2=222&param3=333

  3. O modelo de mapeamento deve criar a saída JSON abaixo, que é a entrada para sua função Lambda.

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. Você Terminou. A partir deste ponto, a lógica da sua função Lambda pode usar os parâmetros da string de consulta.
    Boa sorte!

Lior Kirshner
fonte
0

Você pode usar o Lambda como "Integração de proxy do Lambda" ; refira-o a [ https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda. html # api-gateway-proxy-integração-lambda-função-python] , opções disponíveis para este lambda são

Para os Nodejs Lambda 'event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables' e 'event.requestContext'

Para o evento Python Lambda ['headers'] ['parametername'] e assim por diante

RajDev
fonte
-1

Depois de ler várias dessas respostas, usei uma combinação de várias em agosto de 2018 para recuperar os parâmetros de cadeia de consulta através do lambda para python 3.6.

Primeiro, fui ao API Gateway -> Minha API -> recursos (à esquerda) -> Pedido de integração. Na parte inferior, selecione Modelos de Mapeamento e, em seguida, digite o tipo de conteúdo application/json.

Em seguida, selecione o modelo de Passagem de solicitação de método fornecido pela Amazon e selecione salvar e implantar sua API.

Então, lambda event['params']é como você acessa todos os seus parâmetros. Para a sequência de consultas:event['params']['querystring']

Jghorton14
fonte