Как обеспечить согласованный доступ к полезной нагрузке AWS лямбда с помощью различных методов вызова

В зависимости от документации AWS, которую я читаю, я вижу разные методы доступа к полезной нагрузке функций AWS Lambda, что приводит к разным и несовместимым реализациям.

Обычно, согласно документации AWS и практическим экспериментам, на примере лямбды, вычисляющей area на основе length и width, нам потребуются разные реализации для поддержки этих двух вызовов:

aws lambda invoke  --function-name $MY_LAMBDA_NAME \
    --payload '{"length": 10, "width": 10}' \
    --cli-binary-format raw-in-base64-out /dev/stdout

И:

curl $MY_LAMBDA_URL -H 'Content-Type: application/json' \
    -d '{"length": 10, "width": 10}'

Например, в Начало работы с Lambdaevent — это документ JSON, содержащий полезную нагрузку. В документации указано: «Если ваша функция вызывается другим сервисом AWS, объект события содержит информацию о событии, вызвавшем вызов». Предоставленный пример реализации работает, как описано, при вызове лямбды через консоль, aws cli и т. д. Он не работает при вызове лямбды через Curl, Postman и т. д. Доступ к length и width выглядит следующим образом:

def lambda_handler(event, context):
    length = event["length"]
    width = event["width"]
    ...

На других страницах документации AWS полезная нагрузка представляет собой строку, доступную через eventbody. Одним из таких примеров является Учебное пособие: Создание лямбда-функции с URL-адресом функции. Предоставленный пример реализации работает при вызове лямбды через Curl, Postman и т. д. Однако он не будет работать при вызове лямбды через консоль, aws cli и т. д. В этом случае доступ к length и width выглядит следующим образом (концептуальное преобразование из узла в питон):

def lambda_handler(event, context):
    # requires more work to check for encoding, etc.
    body = json.loads(event["body"])
    length = body["length"]
    width = body["width"]
    ...

Помимо бездействия, я могу придумать два очевидных способа устранить это несоответствие:

  1. задокументируйте лямбду, чтобы сообщить пользователю, предназначена ли лямбда для использования через другие сервисы AWS или нет, и позвольте тем, кто пропустит эту часть документа, выяснить причину, по которой определенные ключи недоступны в event и почему такое поведение варьируется в зависимости от контекста
  2. добавьте дополнительный код для поддержки обоих вариантов использования на основе содержимого event (в основном проверяет, содержит ли он body или нет, поддерживает различные кодировки и т. д.)

Первый вариант неудовлетворителен, поскольку вызывает ненужную головную боль при обслуживании. Второй вариант неуклюж и может вызвать недоумение у разработчиков, которые не читали эту часть документа.

Каковы разумные варианты устранения этого несоответствия? Есть ли в документации AWS разделы, содержащие хорошие рекомендации? Есть ли способы настроить лямбды AWS, чтобы устранить несоответствие? Существуют ли способы вызова лямбды, которые приводят к единообразному поведению независимо от того, вызывается ли она через другой сервис AWS или нет?

Как сделать HTTP-запрос в Javascript?
Как сделать HTTP-запрос в Javascript?
В JavaScript вы можете сделать HTTP-запрос, используя объект XMLHttpRequest или более новый API fetch. Вот пример для обоих методов:
2
0
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Функции AWS Lambda обычно пишутся с явным знанием данных, которые передаются им через event. Редко можно написать функцию, которая получает разные типы входных данных.

Это похоже на обычную «функцию», которую можно использовать в программе Python: функции пишутся так, чтобы принимать определенные входные данные и выполнять определенные действия. Редко можно написать функцию на Python, которая должна выяснить, какие входные данные ей были переданы и что она должна делать с этими входными данными.

В ваших примерах, если функция предназначена для вычисления площади прямоугольника, то в качестве входных данных она будет ожидать length и width. Он не знает, как обрабатывать событие, генерируемое Amazon S3 при создании нового объекта, и не должен этого делать — цель функции — вычислить площадь прямоугольника, а не реагировать на создание новых объектов.

Как и при определении функции на любом языке программирования, знание входных данных очень важно для написания функции.

Если вы не понимаете, что передается в функцию, вы можете добавить print(event) в начало lambda_handler() функции. Это выведет содержимое события в журнал. Вы можете использовать CloudWatch Events, чтобы просмотреть журнал и узнать, что было передано в функцию.

Вас также может заинтересовать Анонс URL-адресов функций AWS Lambda: встроенные конечные точки HTTPS для однофункциональных микросервисов | Блог новостей AWS. Это дает возможность вызвать функцию Lambda из Интернета без использования шлюза API.

Спасибо за ваш ответ. Я полностью согласен с тем, что «как и определение функции на любом языке программирования, знание входных данных очень важно для написания функции». Исходя из этого, могли бы вы предложить, как справиться с тем фактом, что мы получаем разные события в зависимости от того, как вызывается лямбда?

Come Raczy 14.06.2024 03:44

Обычно для каждого типа ввода используются разные лямбда-функции. Например, если вы реагируете на новые объекты, создаваемые в S3, вы, вероятно, захотите выполнить операции над объектом. Если вы отвечаете на сообщения из очереди Amazon SQS, вам, вероятно, захочется что-то сделать с содержимым сообщения. Если вы отвечаете на запросы API-шлюза, вы, вероятно, захотите обработать данные, предоставленные в HTTP-запросе. Каждый из них представляет собой совершенно разные варианты использования, и их следует обрабатывать с помощью разных функций Lambda.

John Rotenstein 14.06.2024 04:10

Извините, если я утомляю, но это настолько удивительно, что мне хотелось бы подтверждения. Вы хотите сказать, что если мне нужен один сервис «calculate_area», который принимает длину и ширину в качестве входных данных и возвращает площадь=длина*ширина, я должен реализовать, развернуть и управлять двумя разными лямбда-выражениями: «calculate_area_when_invoked_through_aws» и «calcul_area_when_invoked_ Differently»? Это то, что обычно делают люди в мире AWS? Если да, то как они справляются с понесенными накладными расходами? Для этого нужны лямбда-слои?

Come Raczy 14.06.2024 16:08

@ComeRaczy Обычно вы пишете одну лямбда-функцию для каждого процесса (например, вычисления площади). Все, что вызывает эту функцию, желательно передавать входные данные таким же образом (например, JSON, содержащий length и width). Я не уверен, что вы подразумеваете под «вызывать через AWS» и «вызывать по-другому», но вы можете закодировать функцию, которая будет принимать любые входные данные и выполнять любую операцию по вашему желанию — это ваш код, поэтому вы можете делать то, что хотите. ты хочешь.

John Rotenstein 15.06.2024 09:17

@JohnRotenstein, это и есть суть проблемы: AWS не передает входные данные так же, как Curl. если я реализую лямбду, чтобы можно было вызывать ее дома с помощью Curl, width и length находятся внутри элемента body. Если по какой-либо причине я решу вызвать лямбду через любую функциональность AWS, например. aws lambda invoke — Мне нужно изменить реализацию, иначе лямбда выйдет из строя, потому что AWS передает входные данные по-другому — доступ к length и width должен осуществляться напрямую, а не к элементу body. И я, кажется, не могу это контролировать, потому что это вне моего кода.

Come Raczy 16.06.2024 18:45

Если вы используете aws lambda invoke, вы можете предоставить полезную нагрузку, соответствующую curl. Например, --payload '{"body": {"length": 10, "width": 10}}' Вас также может заинтересовать: Анонс URL-адресов функций AWS Lambda: встроенные конечные точки HTTPS для однофункциональных микросервисов | Блог новостей AWS

John Rotenstein 17.06.2024 00:01

@JohnRotenstein Это действительно то, что меня интересовало! Поначалу это казалось немного жестковатым, но эти URL-адреса лямбда-функций, безусловно, имеют большую ценность. Пожалуйста, добавьте это к своему ответу, чтобы я мог его принять. Большое спасибо за ваше время и приверженность.

Come Raczy 18.06.2024 02:05

Другие вопросы по теме