2015-07-30 7 views
135

У меня есть 2 функции лямбда - одна, которая производит цитату, и одну, которая превращает цитату в заказ. Я бы хотел, чтобы функция лямбда заказа вызывала функцию Quote, чтобы восстановить цитату, а не просто получать ее от ненадежного клиента.Может ли функция AWS Lambda вызвать другую

Я искал всюду, о чем я могу думать, но не могу понять, как я буду заниматься цепочкой или вызывать функции ... конечно, это существует!

+1

Я добираюсь сюда, но почему вы не можете зависеть от SDK JavaScript AWS в первой функции Lambda, создайте [AWS.Lambda] (http://docs.aws.amazon.com/AWSJavaScriptSDK/latest /AWS/Lambda.html) client и [invoke] (http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html#invoke-property) вторую функцию? – devonlazarus

+0

Это то, что я собирался попробовать, но я не был полностью уверен, как это сделать, поскольку не было никаких примеров сделать это из другой функции лямбда. – Silver

+1

, очевидно, вы также можете вызвать функцию лямбда через [HTTP] (http://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html). – devonlazarus

ответ

177

Я нашел способ, используя aws-sdk.

var aws = require('aws-sdk'); 
var lambda = new aws.Lambda({ 
    region: 'us-west-2' //change to your region 
}); 

lambda.invoke({ 
    FunctionName: 'name_of_your_lambda_function', 
    Payload: JSON.stringify(event, null, 2) // pass params 
}, function(error, data) { 
    if (error) { 
    context.done('error', error); 
    } 
    if(data.Payload){ 
    context.succeed(data.Payload) 
    } 
}); 

Вы можете найти документ здесь: http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html

+12

Использование SNS, вероятно, лучший подход, но это правильный ответ. – Silver

+0

Ты заработал? Я получаю ошибки маркера безопасности, когда я пытаюсь вызвать лямбда-функцию из другой лямбда-функции. – Jay

+0

Мне тоже интересно об этом. Моя подобная версия не работает, и я подозреваю, что причина связана с безопасностью. – JohnAllen

63

Вы должны направить Lambda functions через SNS. Этот подход обеспечивает хорошую производительность, латентность и масштабируемость для минимальных усилий.

Ваш первый Lambda публикует сообщения на ваш SNS Topic, а второй Lambda подписан на эту тему. Как только сообщения прибудут в тему, второй Lambda будет выполнен с сообщением в качестве входного параметра.

См. Invoking Lambda functions using Amazon SNS notifications.

Вы также можете использовать этот подход для Invoke cross-account Lambda functions via SNS.

+0

, который лучше подходит SNS или Kinesis? Я действительно сомневаюсь, спасибо. –

+1

Kinesis может быть немного сложнее, но если вы ищете более надежное решение, то это может быть хорошим вариантом для вас. Кроме того, SNS не сохраняет входящие события, Kinesis делает. – kixorz

+0

Ссылка на документы будет приятной. – kev

40

вот пример кода для питона,

from boto3 import client as boto3_client 
from datetime import datetime 
import json 

lambda_client = boto3_client('lambda') 

def lambda_handler(event, context): 
    msg = {"key":"new_invocation", "at": datetime.now()} 
    invoke_response = lambda_client.invoke(FunctionName="another_lambda_", 
              InvocationType='Event', 
              Payload=json.dumps(msg)) 
    print(invoke_response) 

Btw, вам нужно будет добавить политику, как это к вашей лямбда роли, а

{ 
     "Sid": "Stmt1234567890", 
     "Effect": "Allow", 
     "Action": [ 
      "lambda:InvokeFunction" 
     ], 
     "Resource": "*" 
    } 
+0

Документация, похоже, предполагает, что полезная нагрузка должна быть JSON. Можно ли отправлять двоичные данные? – mbatchkarov

+1

Я тоже предпочитаю этот метод, но у него есть один глюк. Вам нужно будет преобразовать 'datetime.now()' в строку (или обработать ее каким-то образом). В противном случае вы получите сообщение об ошибке 'datetime.datetime (2017, 9, 11, 14, 40, 53, 23834) не JSON serializable' –

+0

Возможно ли быть более ограничительным в первой роли лямбда? То есть, привязать его к вызову _специфических_ функций, а не всех и всех? – Phil

0

Вы можете вызвать функцию лямбда непосредственно (по крайней мере, с помощью Java), используя AWSLambdaClient, как описано в блоге AWS»post ,

1

Я работал с ответом, blueskin, но я не мог прочитать ответ Payload, потому что InvocationType = «Event» является асинхронной, поэтому я изменил, как InvocationType = «RequestResponse» и теперь все работает хорошо.

1

У меня такая же проблема, но функция Lambda, которую я реализую, введет запись в DynamoDB, поэтому мое решение использует триггеры DynamoDB.

Я заставляю БД вызывать функцию Lambda для каждой вставки/обновления в таблице, поэтому это отделяет реализацию двух функций лямбда.

Документации находится здесь: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.Lambda.html

Вот пошаговая инструкция: https://aws.amazon.com/blogs/aws/dynamodb-update-triggers-streams-lambda-cross-region-replication-app/

1

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

Если вы не хотите устанавливать POST-запрос, вы можете просто настроить простой запрос GET с помощью пары или вообще не использовать параметры строки запроса для упрощения передачи события.

- Edit -

См: https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/

и: http://docs.aws.amazon.com/lambda/latest/dg/with-on-demand-https-example.html

+1

это кажется намного менее крутым, чем SNS, но тогда у меня нет большого опыта использования SNS – Brandon

+0

Можете ли вы поделиться кодом, необходимым для вызова конечной точки API изнутри лямбда? – Glenn

+0

@Glenn - это просто запрос ajax. Пометьте те параметры, которые вам нужны в качестве параметров запроса. См. Https://docs.aws.amazon.com/apigateway/api-reference/making-http-requests/ и http://docs.aws.amazon.com/lambda/latest/dg/with-on-demand -https-example.html – Anselm

9

Я смотрел на вырезание SNS, пока я не видел это в Lambda client docs (Java version):

Клиент для доступа к AWS Lambda. Все служебные вызовы, выполненные с использованием этого клиента, блокируются и не возвращаются до завершения вызова службы.

Таким образом, SNS имеет очевидное преимущество: оно асинхронно. Ваша лямбда не будет ждать завершения следующей лямбды.

+11

InvocationType = «Событие» делает его асинхронным. http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Lambda.html#invoke-property – Ankit

+3

@Ankit, который должен быть выбранным ответом, я был введен в заблуждение, полагая, что использование SNS было единственным способом сделать асинхронный потому что никто не ответил этой информацией. –

+0

@ Ankit знаете ли вы пример использования InvocationType = 'Event', но из Java вместо JavaScript? Существует тонна документации по Java, но не так много примеров, как JavaScript – Talador12

1

В Java, мы можем сделать следующее:

AWSLambdaAsync awsLambdaAsync = AWSLambdaAsyncClientBuilder.standard().withRegion("us-east-1").build(); 

InvokeRequest invokeRequest = new InvokeRequest(); 
invokeRequest.withFunctionName("youLambdaFunctionNameToCall").withPayload(payload); 

InvokeResult invokeResult = awsLambdaAsync.invoke(invokeRequest); 

Здесь полезной нагрузка вашего строкового Java объекта, который должен быть принят в качестве объекта Json другой лямбды в случае, если вам нужно передать какую-то информацию от назвав лямбда названным лямбдой.

0

Вы можете установить окружение AWS_REGION.

assert(process.env.AWS_REGION, 'Missing AWS_REGION env (eg. ap-northeast-1)'); 
const aws = require('aws-sdk'); 
const lambda = new aws.Lambda(); 
2

Поскольку этот вопрос был задан вопрос, Amazon выпустила функции Step (https://aws.amazon.com/step-functions/).

Одним из основных принципов, лежащих в основе AWS Lambda, является то, что вы можете больше сосредоточиться на бизнес-логике и меньше на логике приложения, которая связывает все это вместе. Шаговые функции позволяют организовывать сложные взаимодействия между функциями без необходимости писать код для этого.

Смежные вопросы