Cara meneruskan parameter kueri atau rute ke AWS Lambda dari Amazon API Gateway

348

misalnya jika kita ingin menggunakan

GET /user?name=bob

atau

GET /user/bob

Bagaimana Anda akan melewatkan kedua contoh ini sebagai parameter ke fungsi Lambda?

Saya melihat sesuatu tentang pengaturan "pemetaan dari" dalam dokumentasi, tetapi saya tidak dapat menemukan pengaturan itu di konsol API Gateway.

  • method.request.path.parameter-nameuntuk parameter jalur bernama parameter-namesebagaimana didefinisikan di halaman Permintaan Metode.
  • method.request.querystring.parameter-nameuntuk parameter string kueri bernama parameter-namesebagaimana ditentukan di halaman Permintaan Metode.

Saya tidak melihat salah satu dari opsi ini meskipun saya mendefinisikan string kueri.

MonkeyBonkey
sumber

Jawaban:

299

Mulai September 2017, Anda tidak perlu lagi mengkonfigurasi pemetaan untuk mengakses badan permintaan.

Yang perlu Anda lakukan adalah memeriksa, "Gunakan integrasi Proxy Lambda", di bawah Permintaan Integrasi, di bawah sumber daya.

masukkan deskripsi gambar di sini

Anda kemudian dapat mengakses parameter kueri, parameter jalur, dan header seperti itu

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
Jonathan
sumber
23
Ini tip yang bagus. Namun, perlu diingat bahwa mengaktifkan Lambda Proxy Integration dapat menyebabkan kesalahan "Respon Lambda Proxy Response" salah. Berikut cara memperbaikinya: stackoverflow.com/questions/43708017/…
AaronBaker
5
apakah ada cara untuk melakukan ini di java, sambil menjaga deserialisasi transparan yang RequestHandlerdisediakan oleh implementasi ?
sepatu
2
di mana pengaturan ini?
red888
2
@MattWestlake Anda membuat sumber daya yang disebut pengguna dan di bawahnya sumber daya yang disebut {name} di API Gateway.
Jonathan
3
Saya hanya ingin menyebutkan bahwa setelah perubahan ini saya juga harus pergi ke Amazon API Gateway -> Actions -> Deploy API dan gunakan kembali ke lingkungan live.
victorvartan
221

Langkah-langkah untuk membuat ini berfungsi adalah:

Dalam Konsol API Gateway ...

  1. pergi ke Resources -> Integration Request
  2. klik pada ikon plus atau edit di sebelah templat dropdown (anehnya saya tahu karena bidang templat sudah terbuka dan tombol di sini terlihat berwarna abu-abu)
  3. Ketikkan secara eksplisit application/jsonbidang isian tipe konten meskipun isinya default (jika Anda tidak melakukannya, itu tidak akan disimpan dan tidak akan memberi Anda pesan kesalahan)
  4. letakkan ini di pemetaan input { "name": "$input.params('name')" }

  5. klik pada kotak centang di sebelah dropdown templates (Saya berasumsi inilah yang akhirnya menyelamatkannya)

MonkeyBonkey
sumber
9
Apakah Anda pernah mendapatkan ini untuk mengirim melalui parameter URL di URL seperti / user / bob di mana rute itu / user / {username}? Saya telah mencoba semua jenis permutasi, tetapi tidak dapat menyelesaikannya.
Lucas
5
apakah ada yang tahu jika ada dokumentasi resmi? akan menyenangkan untuk hanya melewati semua parameter kueri atau menangani nilai-nilai opsional lebih anggun daripada string kosong
AxelTheGerman
6
Satu tip untuk pengembang iOS: API Gateway tidak akan meneruskan data kueri hingga Anda menentukan setiap variabel sebagai string kueri (di bawah 'Metode Permintaan') DAN menggunakan API. Sampai penerapannya berfungsi dari uji konsol, tetapi memotong dari permintaan aplikasi.
AlexeyVMP
3
@axel didokumentasikan di sini: docs.aws.amazon.com/apigateway/latest/developerguide/…
russau
6
Lucas, saya membuatnya bekerja menggunakan pola / user / {username}. Ingat saja jika jalur sumber daya GET Anda adalah / user / {username}, pada langkah 4 pemetaan input terlihat seperti {"name": "$ input.params ('username')"}
Gerard
134

Saya telah menggunakan templat pemetaan ini untuk menyediakan Parameter String Kueri, Tajuk, Metode, Jalur, dan URL ke acara Lambda. Saya menulis posting blog yang menjelaskan templat lebih detail: http://kennbrodhagen.net/2015/12/12/bagaimana-untuk-membuat-a-meminta-objek-untuk-Anda-lambda-event-from-api- pintu gerbang/

Di sini adalah Templat Pemetaan yang dapat Anda gunakan:

{
  "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
sumber
Luar biasa! Saya berjuang dengan memberikan barang secara umum kepada pawang saya. Jawaban terbaik di sini.
Venkat D.
Saya melakukan ini, tetapi saya belum mendapatkan apa-apa. Ini menunjukkan Undefined. Bagaimana seharusnya kita mengirim Parameter di URL? dan apakah kita perlu menentukan nama variabel dalam url seperti dalam skenario GET url yang normal? Tolong bantu saya dengan ini.
Parthapratim Neog
8
Bagaimanapun saya mendapat hasilnya. Masalahnya adalah, saya menambahkan pemetaan dan hanya menyimpannya, dan tidak deploymenyalakan api sekali lagi. Setelah saya menggunakan api dengan pemetaan baru, itu berfungsi dengan baik. Terima kasih banyak.
Parthapratim Neog
@ shashu10 Lihat jawaban saya
matsev
1
Saya tidak bisa mulai memberi tahu Anda seberapa bermanfaat blog Anda. Saya menemukan pos "eturn-html-from-aws-api-gateway" pertama dan mengikutinya, karena itulah yang saya butuhkan. Sekarang saya perlu memberikan beberapa parameter ke fungsi dan memodifikasi html berdasarkan itu - dan lagi Anda satu-satunya dengan panduan nyata! Semua panduan lain yang saya temukan tampaknya tidak penting.
user3685427
41

Saat ini templat tarik-turun disertakan dalam Konsol Gateway API di AWS.

Untuk API Anda, klik pada nama sumber daya ... lalu DAPATKAN

Luaskan "Templat Pemetaan Tubuh"

Ketikkan

aplikasi / json

untuk Jenis-Konten (harus diketik secara eksplisit) dan klik tanda centang

Jendela baru akan terbuka dengan kata-kata "Hasilkan template" dan dropdown (lihat gambar).

Pilih

Permintaan Metode passthrough

masukkan deskripsi gambar di sini

Kemudian klik simpan

Untuk mengakses variabel apa pun, cukup gunakan sintaks berikut (ini adalah Python) misalnya URL:

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

Anda bisa mendapatkan variabel sebagai berikut:

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

Jadi tidak perlu menyebutkan atau memetakan secara eksplisit setiap variabel yang Anda inginkan.

Dirk Conrad Coetsee
sumber
luar biasa! fungsinya ada di sana dalam layanan tetapi telah melewatkannya!
hnvasa
25

Untuk meneruskan parameter ke fungsi lambda Anda, Anda perlu membuat pemetaan antara permintaan API Gateway dan fungsi lambda Anda. Pemetaan dilakukan di Integration Request-> Mapping templatesbagian sumber daya API Gateway yang dipilih.

Buat pemetaan jenis application/json, maka di sebelah kanan Anda akan mengedit (klik pensil) templat.

Template pemetaan sebenarnya adalah template Velocity di mana Anda dapat menggunakan ifs, loop, dan tentu saja mencetak variabel di atasnya. Template memiliki variabel-variabel ini yang disuntikkan di mana Anda dapat mengakses parameter querystring, header permintaan, dll. Secara individual. Dengan kode berikut, Anda dapat membuat ulang seluruh querystring:

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

Catatan: klik pada simbol centang untuk menyimpan templat. Anda dapat menguji perubahan Anda dengan tombol "test" di sumber Anda. Tetapi untuk menguji parameter querystring di konsol AWS, Anda perlu menentukan nama parameter di Method Requestbagian sumber daya Anda.

Catatan: lihat Panduan Pengguna Velocity untuk informasi lebih lanjut tentang bahasa templating Velocity.

Kemudian dalam templat lambda Anda, Anda bisa melakukan yang berikut untuk mendapatkan querystring diuraikan:

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
gimenete
sumber
9
Ini solusi terbaik. Harap ingat untuk melakukannya Actions>Deploy API(saya membuang-buang waktu untuk melupakan ini ...). Lambda arn yang terkait akan mengambil perubahan segera setelah penempatan. Anda dapat memeriksanya Stages > #stage (like: prod) > Deployment History.
loretoparisi
24

Jawaban yang diterima bekerja dengan baik untuk saya, tetapi memperluas pada jawaban gimenete, saya ingin templat generik yang dapat saya gunakan untuk melewati semua params kueri / path / header (seperti string untuk saat ini), dan saya datang dengan templat berikut. Saya mempostingnya di sini kalau-kalau ada yang merasa berguna:

#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
sumber
1
Hebat, saya ingin dapat menggunakan fungsi yang sama untuk permintaan POST (dengan JSON body) dan DAPATKAN dengan string kueri. Mimpi berhasil. Terima kasih!
Matt Fletcher
@ Benv apakah ini templat lengkap?
nxmohamad
17

Sebagai bagian dari mencoba menjawab salah satu pertanyaan saya sendiri di sini , saya menemukan trik ini.

Di templat pemetaan Gateway API, gunakan yang berikut untuk memberi Anda string kueri lengkap seperti yang dikirim oleh klien HTTP:

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

Keuntungannya adalah Anda tidak perlu membatasi diri pada serangkaian kunci yang dipetakan yang telah ditentukan sebelumnya dalam string kueri Anda. Sekarang Anda dapat menerima pasangan nilai kunci dalam string kueri, jika ini yang ingin Anda tangani.

Catatan: Menurut ini , hanya $input.params(x)terdaftar sebagai variabel yang tersedia untuk template VTL. Ada kemungkinan bahwa internal mungkin berubah dan querystringmungkin tidak lagi tersedia.

user3526
sumber
1
Ini masih berfungsi pada Mei 2017 tetapi mengembalikan objek JS yang diciptakan API Gateway untuk Anda daripada string kueri yang sebenarnya. Ini menjengkelkan bagi saya karena saya mencoba mengurai string kueri untuk mengubah param yang diulang menjadi sebuah array.
Tom Saleeba
11

Sekarang Anda harus dapat menggunakan tipe integrasi proxy baru untuk Lambda untuk secara otomatis mendapatkan permintaan penuh dalam bentuk standar, daripada mengkonfigurasi pemetaan.

lihat: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on- proksi-sumber daya

jackko
sumber
1
Saya tidak yakin mengapa, tetapi integrasi proxy biasanya tidak berfungsi untuk saya. Saya harus menghapusnya dari API terbaru yang saya buat.
Gustavo Straube
sama ^ selanjutnya saya punya masalah CORS dengan API Gateway. Mengikuti bersama dengan dokumen AWS saya tidak bisa membuat CORS bekerja. Namun saya menemukan artikel Medium lama dari pertengahan akhir 2015 yang memiliki cara manual untuk mengatur CORS dan itu berhasil.
Stephen Tetreault
7

DAPATKAN / pengguna? Nama = bob

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

DAPATKAN / pengguna / bob

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

Banyak jawaban di sini luar biasa. Tetapi saya menginginkan sesuatu yang sedikit lebih sederhana. Saya menginginkan sesuatu yang akan bekerja dengan sampel "Hello World" secara gratis. Ini berarti saya ingin sederhana menghasilkan badan permintaan yang cocok dengan string kueri:

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

Saya pikir jawaban teratas menghasilkan sesuatu yang lebih berguna ketika membangun sesuatu yang nyata, tetapi untuk menjalankan dunia hello cepat menggunakan templat dari AWS ini bekerja dengan baik.

KrisTC
sumber
4

Contoh pemetaan parameter berikut melewati semua parameter, termasuk path, querystring dan header, hingga ke titik akhir integrasi via 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
  }
}

Akibatnya, templat pemetaan ini menampilkan semua parameter permintaan dalam muatan sebagaimana diuraikan sebagai berikut:

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

Disalin dari Panduan Pengembang Amazon API Gateway

matsev
sumber
2

String kueri lurus ke depan untuk mem-parsing dalam javascript di lambda

untuk GET / pengguna? name = bob

 var name = event.params.querystring.name;

Ini tidak memecahkan pertanyaan GET pengguna / bob.

Michael Riecken
sumber
its event.queryStringParameters.name
Neo
Saya harus melakukanevent.queryStringParameters.name
Anders Kitson
2

Sebagai jawaban Jonathan, setelah tandai Gunakan integrasi Proxy Lambda dalam Permintaan Integrasi , dalam kode sumber Anda, Anda harus menerapkan format di bawah ini untuk melewati 502 Bad Gateway error.

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

Jangan lupa gunakan sumber daya Anda di API Gateway sebelum menjalankan kembali API Anda. Respons JSON hanya mengembalikan yang diatur dalam tubuh sudah benar. Jadi, Anda bisa mendapatkan jalur, parameter, header, nilai tubuh dari acara

const {path, queryStringParameters, header, body} = acara;

Long Nguyen
sumber
1

Fungsi Lambda mengharapkan input JSON, oleh karena itu parsing string kueri diperlukan. Solusinya adalah mengubah string kueri ke JSON menggunakan Templat Pemetaan.
Saya menggunakannya untuk C # .NET Core, jadi input yang diharapkan haruslah JSON dengan parameter "queryStringParameters".
Ikuti 4 langkah di bawah ini untuk mencapai itu:

  1. Buka templat pemetaan sumber daya API Gateway Anda dan tambahkan application/jsonkonten-tyap baru:

Template pemetaan API Gateway

  1. Salin templat di bawah ini, yang mem-parsing string kueri ke dalam JSON, dan rekatkan ke templat pemetaan:

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. Di API Gateway, panggil fungsi Lambda Anda dan tambahkan string kueri berikut (misalnya): param1=111&param2=222&param3=333

  3. Template pemetaan harus membuat output JSON di bawah ini, yang merupakan input untuk fungsi Lambda Anda.

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. Kamu sudah selesai. Dari titik ini, logika fungsi Lambda Anda dapat menggunakan parameter string kueri.
    Semoga berhasil!

Lior Kirshner
sumber
0

Anda dapat menggunakan Lambda sebagai "Integrasi Proxy Lambda" , ref ini [ https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda. html # api-gateway-proxy-integrasi-lambda-function-python] , opsi yang tersedia untuk lambda ini adalah

Untuk Nodejs Lambda 'event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables', dan 'event.requestContext'

Untuk acara Python Lambda ['header'] ['parametername'] dan seterusnya

RajDev
sumber
-1

Setelah membaca beberapa jawaban ini, saya menggunakan kombinasi beberapa di Agustus 2018 untuk mengambil params string kueri melalui lambda untuk python 3.6.

Pertama, saya pergi ke API Gateway -> API Saya -> sumber daya (di sebelah kiri) -> Permintaan Integrasi. Di bagian bawah, pilih Mapping Templates lalu untuk tipe konten yang masuk application/json.

Selanjutnya, pilih templat Passthrough Metode Permintaan yang disediakan Amazon dan pilih simpan dan gunakan API Anda.

Kemudian, lambda event['params']adalah cara Anda mengakses semua parameter Anda. Untuk string kueri:event['params']['querystring']

Jghorton14
sumber