Saya memiliki 2 Lambdas menggunakan Chalice di belakang API Gateway. Semua titik akhir dilindungi oleh otorisasi Cognito.

Saat saya memanggil GET /hello, saya ingin Lambda pertama mengambil data dari Lambda kedua:

# 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'})

Permintaan ini tidak harus melalui API Gateway + otorisasi lagi, karena menciptakan overhead yang tidak perlu.

Bagaimana cara melakukan panggilan ini secara langsung?

1
cahen 9 Juli 2020, 16:15

1 menjawab

Jawaban Terbaik

EDIT: Saya merekomendasikan solusi di bawah ini hanya jika Anda tidak dapat memiliki Gateway API Internal untuk alasan apa pun.


Dengan kode di bawah ini saya berhasil memanggil Chalice Lambda lain secara langsung (tanpa melalui API Gateway + Authorizer lagi):

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

    ...

Contoh penggunaan:

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

Panggilan ini sinkron. Untuk membuat versi asinkron di atas, gunakan InvocationType='Event' sebagai didokumentasikan di sini.

Perhatikan bahwa payload yang digunakan di atas akan sama persis jika menggunakan bahasa atau framework lain, mengingat ini adalah format yang dikirim dari API Gateway ke fungsi Lambda.

1
cahen 2 Februari 2021, 17:12