Amazon API Gateway'den AWS Lambda'ya sorgu dizesi veya route parametresi nasıl aktarılır


348

örneğin kullanmak istiyorsak

GET /user?name=bob

veya

GET /user/bob

Bu örneklerin her ikisini de parametre olarak Lambda işlevine nasıl iletirsiniz?

Belgelerde "eşleştirildi" ayarıyla ilgili bir şey gördüm, ancak API Ağ Geçidi konsolunda bu ayarı bulamıyorum.

  • method.request.path.parameter-nameparameter-nameYöntem İsteği sayfasında tanımlandığı şekilde adlandırılan bir yol parametresi için .
  • method.request.querystring.parameter-nameparameter-nameYöntem İsteği sayfasında tanımlandığı şekilde adlandırılan bir sorgu dizesi parametresi için.

Bir sorgu dizesi tanımladığım halde bu seçeneklerden hiçbirini görmüyorum.

Yanıtlar:


299

Eylül 2017 itibarıyla artık istek gövdesine erişmek için eşlemeleri yapılandırmanız gerekmemektedir.

Yapmanız gereken tek şey kaynağın altındaki Entegrasyon Talebi altındaki "Lambda Proxy entegrasyonunu kullan" ı kontrol etmektir.

resim açıklamasını buraya girin

Daha sonra sorgu parametrelerine, yol parametrelerine ve bunun gibi başlıklara erişebileceksiniz.

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

23
Bu harika bir ipucu. Ancak, Lambda Proxy Entegrasyonunu açmanın "Hatalı Biçimlendirilmiş Lambda Proxy Yanıtı" hatasına neden olabileceğini unutmayın. Bunu nasıl düzelteceğiniz aşağıda açıklanmıştır: stackoverflow.com/questions/43708017/…
AaronBaker

6
java'da uygulamanın RequestHandlersağladığı şeffaf serileştirmeyi sürdürmenin bir yolu var mı?
ayakkabı

2
bu ayar nerede?
red888

2
@MattWestlake API Gateway'de user adlı bir kaynak ve bunun altında {name} adlı bir kaynak oluşturursunuz.
Jonathan

3
Ben sadece bu değişiklikten sonra ben de Amazon API Gateway -> Eylemler -> API dağıtmak ve canlı ortama yeniden dağıtmak zorunda bahsetmek istiyorum.
victorvartan

221

Bu işe yarar adımlar:

API Ağ Geçidi Konsolu'nda ...

  1. git Resources -> Integration Request
  2. şablon açılır listesinin yanındaki artı veya düzenle simgesini tıklayın (şablon alanı zaten açık olduğundan ve buradaki düğme gri renkte göründüğünden tek biliyorum)
  3. application/jsonVarsayılan olarak görünse bile içerik türü alanına açıkça yazın (bunu yapmazsanız kaydetmez ve size bir hata mesajı vermez)
  4. bunu girdi eşlemesine koy { "name": "$input.params('name')" }

  5. şablonlar açılır menüsünün yanındaki onay kutusunu tıklayın (nihayet bunu kaydeden şey olduğunu varsayıyorum)


9
Bunu, / user / {username} yolunun olduğu / user / bob gibi URL'lerde URL parametreleri üzerinden gönderdiniz mi? Her türlü permütasyonu denedim, ancak bunu başaramadım.
Lucas

5
herhangi bir resmi belge olup olmadığını bilen var mı? tüm sorgu parametrelerini geçmek veya isteğe bağlı değerleri boş dizelerden daha zarif işlemek güzel olurdu
AxelTheGerman

6
İOS geliştiricileri için bir ipucu: API Ağ Geçidi, her değişkeni sorgu dizesi ('Yöntem İsteği' altında) olarak tanımlayana ve API'yi dağıtana kadar sorgu verilerini iletmez. Konuşlandırılıncaya kadar konsol testinden çalışır, ancak uygulamanın sorgularından kesilir.
AlexeyVMP


6
Lucas, / user / {username} modelini kullanarak çalışmayı başardım. GET kaynak yolunuzun / user / {username} olup olmadığını hatırlayın, 4. adımda giriş eşleme şu {"name": "$ input.params ('username')"} gibi görünür
Gerard

134

Bu eşleme şablonunu Lambda olayına Gövde, Üstbilgiler, Yöntem, Yol ve URL Sorgu Dizesi Parametreleri sağlamak için kullandım. Şablonu daha ayrıntılı olarak açıklayan bir blog yazısı yazdım: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api- Ağ geçidi /

Kullanabileceğiniz Haritalama Şablonu:

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

İnanılmaz! İşleri genel olarak işleyicime aktarmakla uğraşıyordum. En iyi cevap burada.
Venkat D.

Bunu yaptım, ama henüz bir şey elde edemiyorum. Tanımsız gösteriliyor. URL'deki Parametreleri nasıl göndermemiz gerekiyor? ve normal GET URL senaryosunda olduğu gibi URL'deki değişken adını belirtmemiz gerekiyor mu? Lütfen bu konuda bana yardım et.
Parthapratim Neog

8
Sonuçta ben aldım. Sorun şuydu: Haritalamayı ekledim ve yeni kaydettim ve bir deploykez daha API yapmadım . API'yi yeni eşleme ile dağıttığımda, gayet iyi çalıştı. Bir ton teşekkürler.
Parthapratim Neog

@ shashu10 Cevabımı gör
matsev

1
Blogunuzun ne kadar yararlı olduğunu söyleyemem. Önce "eturn-html-from-aws-api-gateway" yazısını buldum ve takip ettim, çünkü tam da ihtiyacım olan şey bu. Şimdi işleve bazı parametreleri iletmem ve buna dayalı olarak html'yi değiştirmem gerekiyor - ve yine gerçek bir rehber olan tek kişi sensin! Bulduğum diğer tüm kılavuzlar noktayı kaçırıyor gibi görünüyor.
user3685427

41

Bu günlerde, AWS'deki API Ağ Geçidi Konsolu'na bir açılır şablon dahil edilmiştir.

API'nız için kaynak adını tıklayın ... sonra GET

Genişlet "Gövde Eşleme Şablonları"

Yazın

uygulama / json

İçerik Türü için (açıkça yazılmalıdır) ve onay işaretini tıklayın

"Şablon oluştur" ve bir açılır menü içeren yeni bir pencere açılacaktır (resme bakın).

seçmek

Yöntem İsteği geçişi

resim açıklamasını buraya girin

Ardından kaydet'i tıklayın

Değişkenlere erişmek için aşağıdaki sözdizimini kullanın (bu Python'dur) örn. URL:

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

Değişkenleri aşağıdaki gibi alabilirsiniz:

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

Bu nedenle, istediğiniz her değişkeni açıkça adlandırmaya veya eşleştirmeye gerek yoktur.


mükemmel! işlevsellik orada hizmet olduğunu ama kaçırmıştı!
hnvasa

25

Parametreleri lambda işlevinize iletmek için API Ağ Geçidi isteği ile lambda işleviniz arasında bir eşleme oluşturmanız gerekir. Eşleme, seçilen API Ağ Geçidi kaynağının Integration Request-> Mapping templatesbölümünde yapılır .

Bir tür eşleme oluşturun application/json, ardından sağda şablonu düzenleyeceksiniz (kurşun kalemi tıklayın).

Bir eşleme şablonu aslında ifs, loop'ları ve elbette üzerinde değişkenleri kullanabileceğiniz bir Velocity şablonudur. Şablonda, sorgu dizeleri parametrelerine, istek başlıklarına vb. Ayrı ayrı erişebileceğiniz bu değişkenler enjekte edilir . Aşağıdaki kod ile tüm sorgu dizesini yeniden oluşturabilirsiniz:

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

Not: şablonu kaydetmek için onay sembolüne tıklayın. Değişikliklerinizi kaynağınızdaki "test" düğmesiyle test edebilirsiniz. Ancak AWS konsolunda sorgu dizesi parametrelerini test etmek Method Requestiçin kaynağınızın bölümünde parametre adlarını tanımlamanız gerekir .

Not: Velocity şablon dili hakkında daha fazla bilgi için Velocity Kullanıcı Kılavuzu'na bakın.

Daha sonra lambda şablonunuzda querystring'i ayrıştırmak için aşağıdakileri yapabilirsiniz:

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

9
Bu en iyi çözümdür. Lütfen Actions>Deploy APIo zaman yapmayı unutmayın (bunu unutmak için zamanımı boşa harcadım ...). İlişkili lambda arn, konuşlandırmadan hemen sonra değişikliği alacaktır. Check-in yapabilirsiniz Stages > #stage (like: prod) > Deployment History.
loretoparisi

24

Kabul edilen cevap benim için iyi çalıştı, ancak gimenete'nin cevabını genişleterek, tüm sorgu / yol / başlık parametrelerini (şimdilik dizeler gibi) geçirmek için kullanabileceğim genel bir şablon istedim ve aşağıdaki şablonu buldum. Birisinin yararlı bulması durumunda buraya gönderiyorum:

#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, ben de POST (JSON gövdeli) istekleri ve sorgu dizeleri ile GET için aynı işlevi kullanmak istedim. Rüya gibi çalışır. Teşekkürler!
Matt Fletcher

@benv bu tam şablon mu?
nxmohamad

17

Kendi sorulardan birini yanıtlayın çalışmakla parçası olarak burada , bu hile karşılaştım.

API Ağ Geçidi eşleme şablonunda, HTTP istemcisi tarafından gönderilen tam sorgu dizesini vermek için aşağıdakileri kullanın:

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

Avantajı, kendinizi sorgu dizenizdeki bir dizi önceden tanımlanmış eşlenmiş anahtarla sınırlamak zorunda kalmamanızdır. Artık bu şekilde işlemek istiyorsanız, sorgu dizesindeki herhangi bir anahtar / değer çiftini kabul edebilirsiniz.

Not: göre bu , sadece $input.params(x)bir değişken VTL şablonu için hazır olarak listelenir. İç kısımların değişmesi ve querystringartık mevcut olmaması mümkündür.


1
Bu hala Mayıs 2017 itibariyle çalışır, ancak API Gateway'in sizin için oluşturduğu JS nesnesini gerçek sorgu dizesi yerine döndürür. Bir diziye tekrarlanan params açmak için sorgu dizesini ayrıştırmaya çalışıyorum çünkü bu benim için sinir bozucu.
Tom Saleeba

11

Artık, eşleştirmeleri yapılandırmak yerine tüm isteği otomatik olarak standart şekilde almak için Lambda için yeni proxy entegrasyon türünü kullanabilmeniz gerekir.

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


1
Neden olduğundan emin değilim, ancak proxy entegrasyonu genellikle benim için çalışmıyor. Oluşturduğum en son API'lardan kaldırmak zorunda kaldım.
Gustavo Straube

aynı ^ dahası API Ağ Geçidi ile CORS sorunları yaşadım. AWS dokümanlarıyla birlikte CORS'i çalıştıramadım. Bununla birlikte, 2015'in ortalarından itibaren CORS kurmanın manuel bir yoluna sahip olan ve işe yarayan eski bir Orta makale buldum.
Stephen Tetreault

7

GET / kullanıcı? Adı = bob

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

GET / kullanıcı / bob

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

5

Buradaki cevapların çoğu harika. Ama biraz daha basit bir şey istedim. "Hello World" örneğiyle ücretsiz olarak çalışacak bir şey istedim. Bu basit bir sorgu dizesiyle eşleşen bir istek gövdesi üretir istediği anlamına gelir:

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

En iyi cevabın gerçek bir şey inşa ederken daha yararlı bir şey ürettiğini düşünüyorum, ancak AWS şablonunu kullanarak çalışan hızlı bir merhaba dünyası elde etmek için bu harika çalışıyor.


4

Aşağıdaki parametre eşleme örneği, yol, sorgu dizesi ve başlık dahil tüm parametreleri bir JSON yükü üzerinden tümleştirme uç noktasına geçirir

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

Aslında, bu eşleme şablonu, yükteki tüm istek parametrelerini aşağıda belirtildiği gibi çıktılar:

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

Amazon API Gateway Geliştirici Kılavuzu'ndan kopyalandı


2

Sorgu dizesi, lambda'daki javascript'te ayrıştırmak için doğrudan ileri

GET / kullanıcı için? name = bob

 var name = event.params.querystring.name;

Bu GET kullanıcı / bob sorusunu çözmez.


event.queryStringParameters.name
Neo

Yapmam gerekiyorduevent.queryStringParameters.name
Anders Kitson

2

Jonathan'ın cevap @ gibi, işareti sonra kullan Lambda Vekil entegrasyonu içinde Entegrasyon Request , kaynak kodunda size pass üzere Biçim aşağıdaki gibi uygulamalıdır 502 Bozuk Ağ Geçidi hatası.

Düğüm JS 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;
};

API'nızı yeniden çalıştırmadan önce kaynağınızı API Ağ Geçidi'nde dağıtmayı unutmayın . Yanıt JSON, vücutta ayarlanan doğru olanı döndürür . Böylece olaydan yol, parametre, başlıklar, gövde değeri alabilirsiniz

const {path, queryStringParameters, üstbilgiler, body} = olay;


1

Lambda işlevi JSON girdisini bekler, bu nedenle sorgu dizesini ayrıştırmak gerekir. Çözüm, Eşleme Şablonu'nu kullanarak sorgu dizesini JSON olarak değiştirmektir.
C # .NET Core için kullandım, bu yüzden beklenen giriş "queryStringParameters" parametresi ile bir JSON olmalıdır.
Bunu başarmak için aşağıdaki 4 adımı izleyin:

  1. API Ağ Geçidi kaynağınızın eşleme şablonunu açın ve yeni application/jsoncontent-tyap ekleyin :

API Ağ Geçidi eşleme şablonu

  1. Sorgu dizesini JSON'a ayrıştıran aşağıdaki şablonu kopyalayın ve eşleme şablonuna yapıştırın:

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. API Ağ Geçidi'nde Lambda işlevinizi arayın ve aşağıdaki sorgu dizesini ekleyin (örnek için): param1=111&param2=222&param3=333

  3. Eşleme şablonu , Lambda işlevinizin girdisi olan aşağıdaki JSON çıktısını oluşturmalıdır .

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. Sen bittin. Bu noktadan sonra, Lambda fonksiyonunuzun mantığı sorgu dizesi parametrelerini kullanabilir.
    İyi şanslar!


0

Lambda'yı "Lambda Proxy Entegrasyonu" olarak kullanabilirsiniz , bunu [ https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda olarak ref . html # api-gateway-proxy-entegrasyonu-lambda-function-python] , bu lambda için geçerli seçenekler

Nodejs Lambda 'event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables' ve 'event.requestContext' için

Python Lambda etkinliği için ['başlıklar'] ['parametreadı'] vb.



-1

Bu cevapların birkaçını okuduktan sonra, 2018 yılının Ağustos ayında birkaçının bir kombinasyonunu python 3.6 için lambda aracılığıyla sorgu dizesi parametrelerini almak için kullandım.

İlk olarak, API Ağ Geçidi -> API'm -> kaynaklarına (solda) -> Entegrasyon İsteğine gittim. Altta, Eşleme Şablonları'nı seçin, ardından içerik türü için girin application/json.

Ardından, Amazon'un sağladığı Yöntem İsteği Geçişi şablonunu seçin ve API'nızı kaydedin ve dağıtın'ı seçin.

Sonra, lambda event['params']tüm parametrelerinize nasıl erişeceğinizdir. Sorgu dizesi için:event['params']['querystring']

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.