Як передати параметр запиту або параметр маршруту до AWS Lambda від шлюзу API Amazon


348

наприклад, якщо ми хочемо використовувати

GET /user?name=bob

або

GET /user/bob

Як би ви передали обидва ці приклади як параметр функції Ламбда?

Я щось бачив у налаштуванні "зіставленого з" документації, але не можу знайти це налаштування в консолі шлюзу API.

  • method.request.path.parameter-nameдля параметра шляху, названого parameter-nameяк визначено на сторінці Запит на метод.
  • method.request.querystring.parameter-nameдля параметра рядка запиту, названого parameter-nameяк визначено на сторінці Запит методу.

Я не бачу жодного з цих параметрів, навіть якщо я визначив рядок запиту.

Відповіді:


299

З вересня 2017 року вам більше не доведеться налаштовувати відображення для доступу до запиту.

Все, що вам потрібно зробити, це встановити прапорець "Використовувати інтеграцію проксі-лямбда", під Запит на інтеграцію, під ресурсом.

введіть тут опис зображення

Потім ви зможете отримати доступ до параметрів запиту, параметрів шляху та заголовків

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

23
Це чудова порада. Але майте на увазі, що включення Lambda Proxy Integration може спричинити помилку "Неправильна відповідь пророк лямбда-проксі". Ось як це виправити: stackoverflow.com/questions/43708017 / ...
AaronBaker

6
чи можна це зробити в java, зберігаючи прозору десяріалізацію, яку RequestHandlerзабезпечує реалізація ?
взуття

2
де це налаштування?
red888

2
@MattWestlake Ви створюєте ресурс, який називається користувачем, і під ним ресурс під назвою {name} в шлюзі API.
Джонатан

3
Я просто хочу зазначити, що після цієї зміни мені також довелося перейти до шлюзу API Amazon API -> Дії -> Розгорнути API та перевтілитись у пряме середовище.
victorvartan

221

Етапи, які допоможуть зробити це:

У консолі шлюзу API ...

  1. йти до Resources -> Integration Request
  2. натисніть значок плюс або редагувати поруч із спадною панеллю шаблонів (як це не знаю, оскільки поле шаблону вже відкрите і кнопка тут виглядає сірою)
  3. Явно введіть application/jsonу полі типу типу вмісту, навіть якщо він показує типовий (якщо ви цього не зробите, він не збереже і не видасть повідомлення про помилку)
  4. помістіть це у вхідне відображення { "name": "$input.params('name')" }

  5. натисніть на прапорець біля спадного шаблону (я припускаю, що це остаточно збереже)


9
Ви коли-небудь отримували це для надсилання через параметри URL-адрес у таких URL-адресах, як / user / bob, де був маршрут / user / {username}? Я пробував усілякі перестановки, але не зміг це зробити.
Лукас

5
хтось знає, чи є офіційна документація? було б добре просто пройти через усі параметри запиту або обробити необов'язкові значення більш витончено, ніж порожні рядки
AxelTheGerman

6
Один підказ для розробників iOS: шлюз API не передасть дані запитів, поки ви не визначите кожну змінну як рядок запиту (у розділі "Запит методу") та розгортання API. До розгортання він працює з консольного тесту, але скорочує запити програми.
ОлексійВМП

3
@axel задокументовано тут: docs.aws.amazon.com/apigateway/latest/developerguide/…
russau

6
Лукас, я змусив його працювати за схемою / user / {username}. Просто пам’ятайте, якщо ваш шлях до ресурсу GET / user / {username}, на кроці 4 відображення вводу виглядає приблизно так {"name": "$ input.params ('username") "}
Gerard

134

Я використовував цей шаблон відображення для надання параметрів тіла, заголовків, методу, шляху та рядка URL-адреси для події Lambda. Я написав повідомлення в блозі, де пояснював шаблон більш детально: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api- шлюз /

Ось шаблон картографування, який ви можете використовувати:

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

Дивовижний! Я боровся з передачею речей своїм обробникам. Найкраща відповідь тут.
Венкат Д.

Я це зробив, але поки нічого не отримую. Його показ не визначений. Як ми повинні надіслати Параметри в URL-адресі? і чи потрібно нам вказати ім'я змінної в URL-адресі, як у звичайному сценарії GET url? Будь ласка, допоможіть мені в цьому.
Партхапратім Неог

8
Не маю на увазі, я отримав результат. Проблема була в тому, що я додав картографування і просто зберег його, і не зробив deployapi ще раз. Після того, як я розгорнув api з новим картою, воно спрацювало чудово. Дякую тонну.
Партхапратім Неог

@ shashu10 Дивіться мою відповідь
matsev

1
Я не можу почати розповідати вам, наскільки корисний ваш блог. Я знайшов пост "eturn-html-from-aws-api-gateway" першим і дотримувався його, тому що це саме те, що мені потрібно. Тепер мені потрібно передати деякі параметри до функції та змінити html на основі цього - і знову ти єдиний із справжнім керівництвом! Усі інші довідники, які я знайшов, здаються, пропускають суть.
user3685427

41

У цей день випадаючий шаблон включений до консолі шлюзу API на AWS.

Для свого API натисніть назву ресурсу ... потім GET

Розгорнути "Шаблони картографічних карт"

Введіть

додаток / json

для типу вмісту (має бути чітко набрано) та натисніть галочку

Відкриється нове вікно зі словами "Створити шаблон" та випадаючому меню (див. Зображення).

Виберіть

Спосіб запиту наскрізний

введіть тут опис зображення

Потім натисніть кнопку "Зберегти"

Щоб отримати доступ до будь-яких змінних, просто використовуйте такий синтаксис (це Python), наприклад URL:

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

Ви можете отримати змінні наступним чином:

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

Тому немає необхідності чітко називати або відображати кожну змінну, яку ви хочете.


відмінно! функціональність є прямо в сервісі, але її пропустили!
hnvasa

25

Для передачі параметрів вашій лямбда-функції вам потрібно створити відображення між запитом шлюзу API і вашою лямбда-функцією. Відображення виконується в розділі Integration Request-> Mapping templatesвибраного ресурсу шлюзу API.

Створіть відображення типу application/json, потім праворуч ви відредагуєте (натисніть олівець) шаблон.

Шаблон відображення - це фактично шаблон швидкості, в якому можна використовувати ifs, цикли і, звичайно, друкувати змінні на ньому. У шаблон вводяться ці змінні, де ви можете отримати доступ до параметрів рядків запитів, заголовків запитів тощо. За допомогою наступного коду ви можете заново створити цілий рядок запитів:

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

Примітка: натисніть на символ перевірки, щоб зберегти шаблон. Ви можете перевірити свої зміни кнопкою "тест" у вашому ресурсі. Але для перевірки параметрів запиту рядків на консолі AWS вам потрібно буде визначити назви параметрів у Method Requestрозділі вашого ресурсу.

Примітка: перегляньте Посібник користувача Velocity, щоб отримати докладнішу інформацію про мову шаблонів Velocity.

Потім у вашому шаблоні лямбда ви можете зробити наступне, щоб проаналізувати рядок запитів:

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

9
Це найкраще рішення. Будь ласка, не забудьте зробити це Actions>Deploy API(я витратив свій час, забувши це ...). Асоційований лямбда-арн змінить зміни відразу після розгортання. Ви можете це перевірити Stages > #stage (like: prod) > Deployment History.
loretoparisi

24

Прийнята відповідь спрацювала для мене чудово, але розширюючи відповідь gimenete, я хотів, щоб загальний шаблон, який я міг би використати, щоб пройти через усі параметри запитів / шляхів / заголовків (так само, як рядки на даний момент), і я придумав наступний шаблон. Я публікую його тут, якщо хтось вважає це корисним:

#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, я хотів би мати можливість використовувати однакову функцію для запитів POST (з тілом JSON) та GET з рядками запитів. Працює мрією. Дякую!
Метт Флетчер

@benv це повний шаблон?
nxmohamad

17

У рамках спроби відповісти на одне із моїх власних питань тут я натрапив на цю хитрість.

У шаблоні відображення шлюзу API використовуйте наступне, щоб отримати повний рядок запитів, надісланий клієнтом HTTP:

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

Перевага полягає в тому, що вам не доведеться обмежувати себе набором заздалегідь визначених ключів у рядку запиту. Тепер ви можете прийняти будь-які пари ключ-значення в рядку запиту, якщо так ви хочете обробити.

Примітка. Відповідно до цього , лише $input.params(x)вказаний як змінна, доступна для шаблону VTL. Можливо, що внутрішні зміни можуть змінитися і querystringбільше не будуть доступні.


1
Це все ще працює з травня 2017 року, але він повертає об'єкт JS, який створений шлюз API для вас, а не фактичну рядок запиту. Для мене це дратує, тому що я намагаюся проаналізувати рядок запиту, щоб перетворити повторні параметри в масив.
Том Салееба

11

Тепер ви повинні мати можливість використовувати новий тип інтеграції проксі для Lambda, щоб автоматично отримувати повний запит у стандартній формі, а не налаштовувати відображення.

див .: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on- проксі-ресурс


1
Я не знаю чому, але інтеграція проксі зазвичай не працює для мене. Мені довелося видалити його з останніх створених API.
Густаво Страубе

Крім того, у мене виникли проблеми CORS з шлюзом API. Слідуючи разом з документами AWS, я не зміг заставити CORS працювати. Однак я знайшов стару статтю "Середній" з середини кінця 2015 року, в якій було створено ручний спосіб створення CORS, і це спрацювало.
Стівен Тетро


5

Багато відповідей тут чудові. Але я хотів чогось більш простого. Мені хотілося чогось, що працюватиме з зразком "Hello World" безкоштовно. Це означає, що я хотів, щоб простий виробляє тіло запиту, яке відповідає рядку запиту:

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

Я думаю, що найкраща відповідь створює щось більш корисне при створенні чогось реального, але для отримання швидкого привітного світу з використанням шаблону від AWS це чудово працює.


4

Наступний приклад відображення параметрів передає всі параметри, включаючи шлях, рядок запитів та заголовок, до кінцевої точки інтеграції через корисну навантаження 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
  }
}

Фактично, цей шаблон відображення виводить усі параметри запиту в корисному навантаженні так, як зазначено наступним чином:

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

Скопійовано з Посібника для розробників шлюзу API Amazon


2

Рядок запиту прямо вперед для розбору javascript у лямбда

для GET / user? name = bob

 var name = event.params.querystring.name;

Це не вирішує питання щодо GET користувача / bob.


its event.queryStringParameters.name
Neo

Мені довелося зробитиevent.queryStringParameters.name
Андерс Кітсон

2

Як @ відповідь Джонатана, після знака інтеграції Використання Lambda проксі в інтеграції запит , в вихідному коді , ви повинні здійснити , як показано нижче форматі байпас 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;
};

Не забудьте розгорнути свій ресурс на шлюзі API перед тим, як запустити API. Відповідь JSON просто поверніть, який набір в тілі є правильним. Отже, ви можете отримати шлях, параметр, заголовки, значення тіла від події

const {шлях, queryStringParameters, заголовки, тіло} = подія;


1

Функція Lambda очікує введення JSON, тому потрібен аналіз рядка запиту. Рішення полягає в тому, щоб змінити рядок запиту на JSON за допомогою шаблону відображення.
Я використовував його для C # .NET Core, тому очікуваний вхід повинен бути JSON з параметром "queryStringParameters".
Виконайте ці 4 кроки нижче, щоб досягти цього:

  1. Відкрийте шаблон відображення вашого ресурсу шлюзу API та додайте новий application/jsonконтент-тип:

Шаблон відображення шлюзу API

  1. Скопіюйте шаблон нижче, який аналізує рядок запиту в JSON, і вставте його в шаблон зіставлення:

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. В шлюзі API зателефонуйте до своєї функції Lambda та додайте наступну рядок запиту (для прикладу): param1=111&param2=222&param3=333

  3. Шаблон відображення повинен створити вихід JSON внизу, який є входом для вашої функції Лямбда.

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. Ви закінчили. З цього моменту логіка функції Lambda може використовувати параметри рядка запиту.
    Удачі!


0

Ви можете використовувати Lambda як "інтеграцію проксі-сервісів Lambda" , уточніть це [ https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda. html # api-шлюз-проксі-інтеграція-лямбда-функція-пітон] , доступними для цього лямбда є параметри

Для Nodejs Lambda 'event.headers', 'event.pathParameters', 'event.body', 'event.stageVariables' та 'event.requestContext'

Для події Python Lambda ['заголовки'] ['ім'я параметра'] тощо



-1

Прочитавши декілька цих відповідей, у серпні 2018 року я використав комбінацію декількох, щоб отримати параметри рядка запиту через лямбда для python 3.6.

Спочатку я перейшов до шлюзу API -> Мій API -> ресурси (зліва) -> Запит на інтеграцію. Внизу виберіть Шаблони картографування, а потім введіть тип вмісту application/json.

Далі виберіть шаблон Запросити найпростіший шаблон, який надає Amazon, і виберіть збереження та розгортання вашого API.

Потім у, лямбда event['params']- це спосіб доступу до всіх своїх параметрів. Для рядка запиту:event['params']['querystring']

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.