Как передать строку запроса или параметр маршрута в AWS Lambda из Amazon API Gateway
Например, если мы хотим использовать
GET /user?name=bob
или же
GET /user/bob
Как бы вы передали оба этих примера в качестве параметра в функцию Lambda?
Я видел кое-что об установке "сопоставленного из" в документации, но я не могу найти этот параметр в консоли API Gateway.
method.request.path.parameter-name
для параметра пути с именемparameter-name
как определено на странице запроса метода.method.request.querystring.parameter-name
для параметра строки запроса с именемparameter-name
как определено на странице запроса метода.
Я не вижу ни одного из этих вариантов, хотя я определил строку запроса.
24 ответа
С сентября 2017 года вам больше не нужно настраивать сопоставления для доступа к телу запроса.
Все, что вам нужно сделать, это проверить "Использовать интеграцию с Lambda Proxy" в разделе "Запрос на интеграцию" в разделе ресурса.
После этого вы сможете получить доступ к параметрам запроса, параметрам пути и заголовкам, как
event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
Шаги, чтобы заставить это работать:
В консоли API Gateway...
- идти к
Resources -> Integration Request
- щелкните значок "плюс" или "Изменить" рядом с раскрывающимся списком шаблонов (странно, я знаю, так как поле шаблона уже открыто, а кнопка здесь выглядит серой)
- Явно введите
application/json
в поле типа содержимого, даже если он показывает значение по умолчанию (если вы этого не сделаете, он не сохранится и не выдаст сообщение об ошибке) положить это в отображении ввода
{ "name": "$input.params('name')" }
установите флажок рядом с раскрывающимся списком шаблонов (я предполагаю, что это, в конечном итоге, сохраняет его)
Я использовал этот шаблон отображения для предоставления параметров строки, заголовка, метода, пути и URL-запроса в событие Lambda. Я написал сообщение в блоге, объясняющее шаблон более подробно: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from-api-gateway/
Вот шаблон отображения, который вы можете использовать:
{
"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
}
}
В наши дни раскрывающийся шаблон включен в консоль API Gateway на AWS.
Для вашего API, нажмите на название ресурса... затем GET
Разверните "Шаблоны картографии тела"
Введите
Применение / JSON
для Content-Type (должен быть явно напечатан) и нажмите галочку
Откроется новое окно со словами "Создать шаблон" и раскрывающийся список (см. Изображение).
Выбрать
Метод запроса прохождения
Затем нажмите Сохранить
Чтобы получить доступ к любым переменным, просто используйте следующий синтаксис (это 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'])
Таким образом, нет необходимости явно называть или отображать каждую переменную, которую вы хотите.
Чтобы передать параметры в вашу лямбда-функцию, вам нужно создать отображение между запросом API-шлюза и вашей лямбда-функцией. Отображение делается в Integration Request
-> Mapping templates
раздел выбранного ресурса API Gateway.
Создайте отображение типа application/json
Затем справа отредактируете (щелкните карандашом) шаблон.
Шаблон отображения на самом деле является шаблоном Velocity, где вы можете использовать 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
Принятый ответ работал хорошо для меня, но, расширив ответ Джименете, я хотел универсальный шаблон, который мог бы использовать для прохождения всех параметров запроса / пути / заголовка (так же, как строки на данный момент), и я пришел к следующему шаблону. Я публикую это здесь на тот случай, если кто-то посчитает это полезным:
#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
}
Как часть попытки ответить на один из моих собственных вопросов здесь, я столкнулся с этой уловкой.
В шаблоне сопоставления шлюза API используйте следующую строку, чтобы получить полную строку запроса, отправленную клиентом HTTP:
{
"querystring": "$input.params().querystring"
}
Преимущество заключается в том, что вам не нужно ограничивать себя набором предопределенных сопоставленных ключей в строке запроса. Теперь вы можете принимать любые пары ключ-значение в строке запроса, если вы хотите именно так.
Примечание: согласно этому, только $input.params(x)
отображается как переменная, доступная для шаблона VTL. Вполне возможно, что внутренние органы могут измениться и querystring
может больше не быть доступным.
Строка запроса проста для разбора в javascript в lambda
для GET / пользователя?name=bob
var name = event.params.querystring.name;
Это не решает вопрос GET user/bob.
Теперь вы должны иметь возможность использовать новый тип интеграции прокси для Lambda, чтобы автоматически получать полный запрос в стандартной форме, а не настраивать сопоставления.
см.: http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html
GET /user? Name = bob
{
"name": "$input.params().querystring.get('name')"
}
GET / пользователь /bob
{
"name": "$input.params('name')"
}
Многие ответы здесь великолепны. Но я хотел что-то немного проще. Я хотел что-то, что будет работать с образцом "Hello World" бесплатно. Это означает, что я хотел, чтобы простое производило тело запроса, которое соответствует строке запроса:
{
#foreach($param in $input.params().querystring.keySet())
"$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
#end
}
Я думаю, что лучший ответ дает что-то более полезное при создании чего-то реального, но для того, чтобы получить быстрый привет, работающий с использованием шаблона от AWS, это прекрасно работает.
В следующем примере сопоставления параметров все параметры, включая путь, строку запроса и заголовок, передаются в конечную точку интеграции через полезную нагрузку 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 Gateway
Для получения параметров запроса вы получаете их в
queryStringParameters
такой объект
const name = event.queryStringParameters.name;
Второй — чистый URL. Если твой путь
/user/{name}
, чтобы получить значение, из которого вы его получаете
pathParameters
такой объект
const name = event.pathParameters.name;
Python 3.8 с boto3 v1.16v - декабрь 2020 г.
Для настройки маршрутов вам необходимо настроить API Gateway для приема маршрутов. в противном случае, кроме базового маршрута, все остальное закончится {отсутствующим токеном аутентификации} или чем-то еще ...
После настройки шлюза API для приема маршрутов убедитесь, что вы включили лямбда-прокси, чтобы все работало лучше,
к маршрутам доступа,
new_route = event['path'] # /{some_url}
для доступа к параметру запроса
query_param = event['queryStringParameters'][{query_key}]
Функция Lambda ожидает ввод данных в формате JSON, поэтому необходимо выполнить синтаксический анализ строки запроса. Решение состоит в том, чтобы изменить строку запроса на JSON с помощью шаблона отображения.
Я использовал его для C# .NET Core, поэтому ожидаемым вводом должен быть JSON с параметром "queryStringParameters".
Для этого выполните следующие 4 шага:
- Откройте шаблон сопоставления вашего ресурса API Gateway и добавьте новый
application/json
Содержание-тяп:
Скопируйте шаблон ниже, который анализирует строку запроса в JSON, и вставьте ее в шаблон отображения:
{ "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end} }
В API-шлюзе вызовите функцию Lambda и добавьте следующую строку запроса (для примера):
param1=111¶m2=222¶m3=333
Шаблон отображения должен создать вывод JSON ниже, который является вводом для вашей лямбда-функции.
{ "queryStringParameters": {"param3":"333","param1":"111","param2":"222"} }
Вы сделали С этого момента логика вашей лямбда-функции может использовать параметры строки запроса.
Удачи!
Как ответ @Jonathan, после отметки " Использовать интеграцию Lambda Proxy в запросе на интеграцию" в исходном коде необходимо реализовать следующий формат, чтобы пропустить ошибку 502 Bad Gateway.
Узел 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 Gateway, прежде чем перезапускать свой API. Ответ JSON просто вернуть, который указан в теле правильно. Таким образом, вы можете получить путь, параметр, заголовки, значение тела из события
const { path, queryStringParameters, headers, body } = событие;
exports.handler = async (event) => {
let query = event.queryStringParameters;
console.log(`id: ${query.id}`);
const response = {
statusCode: 200,
body: "Hi",
};
return response;
};
Моя цель состояла в том, чтобы передать строку запроса, подобную:
protodb?sql=select * from protodb.prototab
в лямбда-функцию Node.js 12 через URL-адрес из шлюза API. Я пробовал ряд идей из других ответов, но действительно хотел сделать что-то в максимально возможном собственном интерфейсе интерфейса API-шлюза, поэтому я придумал то, что сработало для меня (с пользовательского интерфейса для API-шлюза по состоянию на декабрь 2020 г.):
На консоли шлюза API для данного API в разделе ресурсов выберите метод получения. Затем выберите его запрос на интеграцию и заполните данные для лямбда-функции вверху страницы.
Прокрутите вниз и откройте раздел шаблонов сопоставления. Если шаблоны не определены, выберите «Запросить передачу текста» (рекомендуется).
Щелкните Добавить шаблоны сопоставления и создайте шаблон с типом содержимого application/json и нажмите кнопку с галочкой.
Для этого шаблона сопоставления выберите сквозную передачу запроса метода в раскрывающемся списке для создания шаблона, который заполнит текстовое поле под ним общим способом передачи всего AWS.
Нажмите кнопку сохранения.
Теперь, когда я тестировал его, я не мог передать параметр как event.sql в узле JS в функции Lambda. Оказывается, когда шлюз API отправляет параметр запроса URL sql в функцию Lambda, он проходит для Node.js как:
var insql = event.params.querystring.sql;
Таким образом, уловка, которая потребовала у меня некоторого времени, заключалась в том, чтобы использовать JSON.stringify, чтобы показать полный стек событий, а затем продвигаться вниз по разделам, чтобы иметь возможность вытащить параметр sql из строки запроса.
Таким образом, в основном вы можете использовать функцию сквозной передачи по умолчанию в шлюзе API, причем хитрость заключается в том, как параметры передаются, когда вы находитесь в функции Lambda.
Вы можете использовать Lambda в качестве "Lambda Proxy Integration", см. Этот [ https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html -gration -lambda-function-python], доступные для этой лямбды опции:
Для Nodejs Lambda "event.headers", "event.pathParameters", "event.body", "event.stageVariables" и "event.requestContext"
Для события Python Lambda ['headers']['имя_параметра'] и т. Д.
Обратитесь к документу:https://docs.aws.amazon.com/apigateway/latest/developerguide/integrating-api-with-aws-services-lambda.html
Вам необходимо изменить шаблон сопоставления
Мои 2 цента здесь: во многих ответах предлагается активировать опцию «Использовать интеграцию с лямбда-прокси» и получить параметры из$.event.queryStringParameter
или$.event.pathParameters
. Но если у вас активирован Access-Control-Allow-Origin (он же CORS), продолжайте читать.
На момент написания этой публикации интеграция Lambda Proxy и CORS не очень хорошо работали вместе. Мой подход состоял в том, чтобы деактивировать флажок интеграции Lambda Proxy и вручную предоставить шаблоны сопоставления как для запроса, так и для ответа следующим образом:
Образец запроса на:
{
#set($params = $input.params().querystring)
"queryStringParameters" : {
#foreach($param in $params.keySet())
"$param" : "$util.escapeJavaScript($params.get($param))" #if($foreach.hasNext),#end
#end
},
#set($params = $input.params().path)
"pathParameters" : {
#foreach($param in $params.keySet())
"$param" : "$util.escapeJavaScript($params.get($param))" #if($foreach.hasNext),#end
#end
}
}
Имейте в виду, что я назвал свойства какqueryStringParameters
иpathParameters
намеренно, чтобы имитировать имена, которые могла бы сгенерировать интеграция Lambda Proxy . Таким образом, мои лямбда-выражения не сломаются, если однажды я активирую интеграцию с лямбда-прокси.
Шаблон ответа дляapplication/json
:
#set($payload = $util.parseJson($input.json('$')))
#set($context.responseOverride.status = $payload.statusCode)
$payload.body
Как вы читаете их в своей лямбде (питоне)? (при условии, что параметры являются необязательными)
def handler(event, context):
body = event["queryStringParameters"] or {}
result = myfunction(**body)
return {
"statusCode": code,
"headers": {
"content-type": "application/json",
},
"body": result
}
Для меня это работает
- Перейти к запросу на интеграцию
- Параметры строки запроса URL-адреса клика
- нажмите Добавить строку запроса
- в поле имени введите имя запроса, здесь это «имя»
- в поле Mapped From введите "method.request.querystring.name"
Прочитав несколько из этих ответов, я использовал комбинацию из нескольких в августе 2018 года для получения параметров строки запроса через лямбду для python 3.6.
Сначала я зашёл в API Gateway -> My API -> resources (слева) -> Запрос интеграции. Внизу внизу выберите Mapping Templates, затем для типа контента введите application/json
,
Затем выберите шаблон "Метод запроса", который предоставляет Amazon, и выберите "Сохранить и развернуть API".
Потом в лямбду event['params']
это то, как вы получаете доступ ко всем вашим параметрам. Для строки запроса: event['params']['querystring']
Если вы используете JAVA для своих функций Lambda, вы можете использовать Lambada Framework, который позаботится об этом за вас.