Как напрямую вызвать Lambda из другой Lambda, не проходя снова через API Gateway и Authorizer? - PullRequest
0 голосов
/ 09 июля 2020

У меня есть 2 лямбда-выражения, использующие Chalice за шлюзом API. Все конечные точки защищены авторизатором Cognito.

Когда я вызываю GET /hello, я хочу, чтобы первая лямбда-функция извлекала данные из второй лямбда-функции:

# Lambda1
@app.route('/hello')
def say_hello():
    name = # fetch data from Lambda2
    return Response({'message': 'hello ' + name})

# Lambda2
@app.route('/name')
def a_name():
    return Response({'name': 'GLaDOS'})

У этого запроса нет на go через API Gateway + авторизатор снова, так как это создает ненужные накладные расходы.

Как сделать этот вызов напрямую?

1 Ответ

0 голосов
/ 21 июля 2020

С помощью приведенного ниже кода я мог успешно вызвать другую лямбду напрямую (без повторного прохождения через API Gateway + Authorizer):

def invoke_sync(lambda_name: str,
                http_method: str,
                path: str,
                claims: dict,
                path_parameters: dict = None,
                http_request_body: str = None,
                query_string_parameters: dict = None,
                headers: dict = None):

    invoke_payload = {
        'path': path,
        'httpMethod': http_method,
        'headers': headers,
        'multiValueHeaders': {},
        'queryStringParameters': query_string_parameters,
        'multiValueQueryStringParameters': None,
        'pathParameters': path_parameters,
        'stageVariables': None,
        'requestContext': {
            'authorizer': {'claims': claims},
            'path': path,
            'resourcePath': path,
            'httpMethod': http_method,
        },
        'body': http_request_body,
    }

    lambda_response = boto3.client('lambda').invoke(FunctionName=lambda_name,
                                                    InvocationType='RequestResponse',
                                                    Payload=json.dumps(invoke_payload))

    payload = json.loads(lambda_response['Payload'].read())
    status_code = payload['statusCode']

    ...

Пример использования:

invoke_sync(
    lambda_name='Users',
    claims=<claims-in-the-id-token>,
    http_method='GET',
    path='/users/{userId}',
    path_parameters={'userId': 123}
)

Этот вызов синхронный. Чтобы создать асинхронную версию вышеупомянутого, используйте InvocationType='Event' как , задокументированное здесь .

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

...