Come passare un parametro querystring o route a AWS Lambda da Amazon API Gateway


348

per esempio se vogliamo usare

GET /user?name=bob

o

GET /user/bob

Come passeresti entrambi questi esempi come parametro alla funzione Lambda?

Ho visto qualcosa sull'impostazione di un "mappato da" nella documentazione, ma non riesco a trovare tale impostazione nella console del gateway API.

  • method.request.path.parameter-nameper un parametro di percorso denominato parameter-namecome definito nella pagina Richiesta metodo.
  • method.request.querystring.parameter-nameper un parametro della stringa di query denominato parameter-namecome definito nella pagina Richiesta metodo.

Non vedo nessuna di queste opzioni anche se ho definito una stringa di query.

Risposte:


299

A partire da settembre 2017, non è più necessario configurare i mapping per accedere al corpo della richiesta.

Tutto quello che devi fare è selezionare "Usa integrazione proxy Lambda", in Richiesta di integrazione, sotto la risorsa.

inserisci qui la descrizione dell'immagine

Sarai quindi in grado di accedere a parametri di query, parametri di percorso e intestazioni in questo modo

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

23
Questo è un ottimo consiglio. Tuttavia, tieni presente che l'attivazione di Lambda Proxy Integration potrebbe causare un errore "Risposta proxy errata Lambda". Ecco come risolvere il problema: stackoverflow.com/questions/43708017/...
AaronBaker

5
c'è un modo per farlo in Java, pur mantenendo la deserializzazione trasparente RequestHandlerfornita dall'attuazione ?
scarpa

2
dov'è questa impostazione?
red888

2
@MattWestlake Si crea una risorsa chiamata user e sotto di essa una risorsa chiamata {name} in API Gateway.
Jonathan,

3
Voglio solo menzionare che dopo questa modifica ho dovuto anche passare ad Amazon API Gateway -> Azioni -> Distribuisci API e ridistribuisci nell'ambiente live.
victorvartan,

221

I passaggi per farlo funzionare sono:

All'interno della console gateway API ...

  1. vai a Resources -> Integration Request
  2. fai clic sull'icona più o modifica accanto al menu a discesa dei modelli (strano lo so perché il campo modello è già aperto e il pulsante qui appare in grigio)
  3. Digita esplicitamente il campo del tipo application/jsondi contenuto anche se mostra un valore predefinito (in caso contrario, non verrà salvato e non verrà visualizzato un messaggio di errore)
  4. inseriscilo nella mappatura di input { "name": "$input.params('name')" }

  5. fai clic sulla casella di controllo accanto al menu a discesa dei modelli (suppongo che questo sia ciò che alla fine lo salva)


9
Ti è mai capitato di inviarlo tramite parametri URL in URL come / user / bob dove era il percorso / user / {nome utente}? Ho provato tutti i tipi di permutazioni, ma non sono stato in grado di risolverlo.
Lucas,

5
qualcuno sa se c'è qualche documentazione ufficiale? sarebbe bello semplicemente passare attraverso tutti i parametri di query o gestire i valori opzionali in modo più elegante rispetto alle stringhe vuote
AxelTheGerman

6
Un consiglio per gli sviluppatori iOS: API Gateway non passerà i dati delle query fino a quando non si definisce ciascuna variabile come stringa di query (in "Richiesta metodo") E si distribuisce l'API. Fino alla distribuzione funziona dal test della console, ma taglia dalle query dell'app.
AlexeyVMP,


6
Lucas, l'ho fatto funzionare usando il modello / user / {username}. Ricorda solo se il tuo percorso di risorse GET è / user / {nome utente}, al punto 4 la mappatura di input è simile a questo {"nome": "$ input.params ('nome utente')"}
Gerard

134

Ho usato questo modello di mappatura per fornire i parametri della stringa di query Body, Headers, Method, Path e URL all'evento Lambda. Ho scritto un post sul blog spiegando il modello in modo più dettagliato: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api- gateway /

Ecco il modello di mappatura che puoi usare:

{
  "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
  }  
}

Sorprendente! Avevo difficoltà a passare le cose genericamente al mio gestore. La migliore risposta qui.
Venkat D.

L'ho fatto, ma non ricevo ancora nulla. Sta mostrando Undefined. Come dovremmo inviare i parametri nell'URL? e dobbiamo specificare il nome della variabile nell'URL come in un normale scenario GET url? Per favore, aiutatemi con questo.
Parthapratim Neog,

8
Non importa, ho ottenuto il risultato. Il problema era che ho aggiunto la mappatura e l'ho appena salvata, e non deployl'API ancora una volta. Una volta distribuito l'API con la nuova mappatura, ha funzionato perfettamente. Grazie mille.
Parthapratim Neog,

@ shashu10 Vedi la mia risposta
matsev

1
Non posso iniziare a dirti quanto sia utile il tuo blog. Ho trovato prima il post "eturn-html-from-aws-api-gateway" e l'ho seguito, perché è esattamente quello di cui avevo bisogno. Ora ho bisogno di passare alcuni parametri alla funzione e modificare l'html in base a quello - e di nuovo sei l'unico con una vera guida! Tutte le altre guide che ho trovato sembrano mancare il punto.
user3685427

41

Al giorno d'oggi un modello a discesa è incluso nella Console gateway API su AWS.

Per la tua API, fai clic sul nome della risorsa ... quindi OTTIENI

Espandi "Modelli di mappatura del corpo"

Digitare

application / json

per Content-Type (deve essere digitato in modo esplicito) e fare clic sul segno di spunta

Si aprirà una nuova finestra con le parole "Genera modello" e un menu a discesa (vedi immagine).

Selezionare

Passthrough richiesta metodo

inserisci qui la descrizione dell'immagine

Quindi fare clic su Salva

Per accedere a qualsiasi variabile, basta usare la seguente sintassi (questo è Python) ad es. URL:

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

Puoi ottenere le variabili come segue:

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

Quindi non è necessario nominare o mappare esplicitamente ogni variabile desiderata.


eccellente! la funzionalità è proprio lì nel servizio ma l'aveva persa!
hnvasa,

25

Per passare i parametri alla funzione lambda è necessario creare un mapping tra la richiesta gateway API e la funzione lambda. Il mapping viene eseguito nella sezione Integration Request-> Mapping templatesdella risorsa gateway API selezionata.

Crea una mappatura di tipo application/json, quindi a destra modificherai (fai clic sulla matita) il modello.

Un modello di mappatura è in realtà un modello di velocità in cui è possibile utilizzare if, loop e, naturalmente, stampare variabili su di esso. Nel modello sono state iniettate queste variabili in cui è possibile accedere a parametri di querystring, intestazioni di richiesta, ecc. Individualmente. Con il seguente codice è possibile ricreare l'intera stringa di query:

{
    "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: fare clic sul simbolo di spunta per salvare il modello. Puoi testare le tue modifiche con il pulsante "test" nella tua risorsa. Ma per testare i parametri di querystring nella console AWS dovrai definire i nomi dei parametri nella Method Requestsezione della tua risorsa.

Nota: consultare la Guida dell'utente di Velocity per ulteriori informazioni sul linguaggio di template di Velocity.

Quindi nel modello lambda è possibile effettuare le seguenti operazioni per ottenere l'analisi della stringa di query:

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo

9
Questa è la soluzione migliore Per favore, ricordati di fare Actions>Deploy APIallora (ho perso tempo dimenticando questo ...). Il lambda arn associato prenderà la modifica immediatamente dopo la distribuzione. Puoi registrarlo Stages > #stage (like: prod) > Deployment History.
Loretoparisi,

24

La risposta accettata ha funzionato bene per me, ma espandendo la risposta di gimenete, volevo un modello generico che potevo usare per passare attraverso tutti i parametri query / path / header (proprio come stringhe per ora), e ho trovato il modello seguente. Lo sto postando qui nel caso qualcuno lo ritenga 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
}

1
Fab, volevo essere in grado di utilizzare la stessa funzione sia per le richieste POST (con il corpo JSON) sia per GET con stringhe di query. Funziona un sogno. Grazie!
Matt Fletcher,

@benv è questo il modello completo?
nxmohamad,

17

Come parte del tentativo di rispondere a una delle mie domande qui , mi sono imbattuto in questo trucco.

Nel modello di mapping del gateway API, utilizzare quanto segue per fornire la stringa di query completa inviata dal client HTTP:

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

Il vantaggio è che non è necessario limitarsi a un set di chiavi mappate predefinite nella stringa di query. Ora puoi accettare qualsiasi coppia chiave-valore nella stringa di query, se è così che vuoi gestire.

Nota: in base a ciò , $input.params(x)viene elencato solo come variabile resa disponibile per il modello VTL. È possibile che gli interni possano cambiare e querystringpotrebbero non essere più disponibili.


1
Funziona ancora a partire da maggio 2017, ma restituisce l'oggetto JS che API Gateway crea per te anziché la stringa di query effettiva. Questo è fastidioso per me perché sto cercando di analizzare la stringa di query per trasformare i parametri ripetuti in un array.
Tom Saleeba,

11

Ora dovresti essere in grado di utilizzare il nuovo tipo di integrazione proxy per Lambda per ottenere automaticamente la richiesta completa in forma standard, piuttosto che configurare i mapping.

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


1
Non sono sicuro del perché, ma l'integrazione proxy di solito non funziona per me. Ho dovuto rimuoverlo dalle ultime API che ho creato.
Gustavo Straube,

stesso ^ inoltre ho avuto problemi CORS con API Gateway. Seguendo i documenti AWS non sono riuscito a far funzionare CORS. Tuttavia, ho trovato un vecchio articolo Medium di metà della fine del 2015 che aveva un modo manuale di impostare CORS e che ha funzionato.
Stephen Tetreault,

7

OTTIENI / user? Name = bob

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

OTTIENI / utente / bob

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

5

Molte delle risposte qui sono fantastiche. Ma volevo qualcosa di un po 'più semplice. Volevo qualcosa che funzionasse gratuitamente con l'esempio "Hello World". Ciò significa che volevo che un semplice producesse un corpo di richiesta corrispondente alla stringa di query:

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

Penso che la risposta migliore produca qualcosa di più utile quando si costruisce qualcosa di reale, ma per far funzionare rapidamente un mondo ciao usando il modello di AWS, questo funziona alla grande.


4

Il seguente esempio di mappatura dei parametri passa tutti i parametri, inclusi path, querystring e header, all'endpoint di integrazione tramite un payload 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
  }
}

In effetti, questo modello di mappatura genera tutti i parametri di richiesta nel payload come indicato di seguito:

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

Copiato dalla Guida per gli sviluppatori di Amazon API Gateway


2

La stringa di query è semplice da analizzare in javascript in lambda

per GET / user? name = bob

 var name = event.params.querystring.name;

Questo non risolve però la domanda GET user / bob.


its event.queryStringParameters.name
Neo,

Ho dovuto fareevent.queryStringParameters.name
Anders Kitson

2

Come risposta di @ Jonathan, dopo il segno Usa l'integrazione di Lambda Proxy nella richiesta di integrazione , nel tuo codice sorgente devi implementare il formato seguente per superare l' errore 502 Bad Gateway .

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

Non dimenticare di distribuire la tua risorsa su API Gateway prima di rieseguire l'API. Risposta JSON restituisce semplicemente quale set nel corpo è corretto. Quindi, potresti ottenere percorso, parametro, intestazioni, valore del corpo dall'evento

const {percorso, queryStringParameters, headers, body} = evento;


1

La funzione Lambda prevede input JSON, pertanto è necessario analizzare la stringa di query. La soluzione consiste nel modificare la stringa di query in JSON utilizzando il modello di mapping.
L'ho usato per C # .NET Core, quindi l'input previsto dovrebbe essere un JSON con il parametro "queryStringParameters".
Seguire questi 4 passaggi di seguito per ottenere ciò:

  1. Apri il modello di mappatura della tua risorsa gateway API e aggiungi nuovo application/jsoncontent-tyap:

Modello di mapping gateway API

  1. Copia il modello seguente, che analizza la stringa di query in JSON e incollalo nel modello di mapping:

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. Nel gateway API, chiama la tua funzione Lambda e aggiungi la seguente stringa di query (per l'esempio): param1=111&param2=222&param3=333

  3. Il modello di mappatura dovrebbe creare l'output JSON di seguito, che è l' input per la funzione Lambda.

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. Hai finito. Da questo punto, la logica della funzione Lambda può utilizzare i parametri della stringa di query.
    In bocca al lupo!


0

Puoi usare Lambda come "Lambda Proxy Integration" , fai riferimento a questo [ 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] , le opzioni disponibili per questa lambda sono

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

Per l'evento Python Lambda ['headers'] ['parametername'] e così via



-1

Dopo aver letto alcune di queste risposte, ho usato una combinazione di diversi nell'agosto del 2018 per recuperare i parametri della stringa di query tramite lambda per Python 3.6.

Innanzitutto, sono andato su API Gateway -> My API -> risorse (a sinistra) -> Richiesta di integrazione. In basso, seleziona Modelli di mappatura, quindi inserisci il tipo di contenutoapplication/json .

Successivamente, seleziona il modello Passthrough di richiesta metodo fornito da Amazon e seleziona salva e distribuisci la tua API.

Quindi, lambda event['params']è il modo in cui accedi a tutti i tuoi parametri. Per stringa di query:event['params']['querystring']

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.