如何使用AWS Lambda和API Gateway下载ZIP文件

huangapple go评论102阅读模式
英文:

How to Download a ZIP file using AWS Lambda and API Gateway

问题

I want to download files using AWS Lambda triggered by an API Gateway endpoint, for this, my lambda function code compiles several files from S3 and creates a zip file (within the lambda /tmp/ directory) containing the specified files.

I'm having some trouble when downloading the file. I understand I have to return within the lambda response the file I want to download as an IO Stream, encoded in base 64. But when I test the API endpoint using Postman and save the response body as a .zip file and try to open it, it says:

> Unable to expand "response.zip". It is in an unsupported format.

I was taking this documentation as an example, but what's different here is that the example downloads images instead of zip files.

my lambda handler method:

require 'logger'
require './lib/reports'
require 'base64'

$logger = Logger.new($stdout, level: Logger::Severity::INFO)

def handler(event:, context:)
    $logger.info("Starting execution of lambda. AWS_REQUEST_ID: #{context.aws_request_id}")

    prefix = 'reports'
    path = event['path']

    reports = Reports::ReportsZipper.new(prefix, path)
    
    reports.download_and_compress_files

    zip_file_path = reports.zip_file_path

    zip_file = File.new(zip_file_path).read()

    lambda_response = {
        'headers': { 'Content-Type': 'application/zip' },
        'statusCode': 200,
        'body': Base64.encode64(zip_file).force_encoding('UTF-8'),
        'isBase64Encoded': true
    }

    return lambda_response

rescue Exception => e
    $logger.error("Error processing. Event: #{event}, Error: #{e.message}")
    { isBase64Encoded: false, statusCode: 400 }
end

Is there something I'm missing?

英文:

I want to download files using AWS Lambda triggered by an API Gateway endpoint, for this, my lambda function code compiles several files from S3 and creates a zip file (within the lambda /tmp/ directory) containing the specified files.

I'm having some trouble when downloading the file. I understand I have to return within the lambda response the file I want to download as a IO Stream, encoded in base 64. But when I test the API endpoint using postman and saving the response body as a .zip file and I try to open it it says:

> Unable to expand "response.zip". It is in an unsupported format.

.

I was taking this documentation as an example, but what's different here is that the example downloads images instead of zip files.

my lambda handler method:

require 'logger'
require './lib/reports'
require 'base64'

$logger = Logger.new($stdout, level: Logger::Severity::INFO)

def handler(event:, context:)
    $logger.info("Starting execution of lambda. AWS_REQUEST_ID: #{context.aws_request_id}")

    prefix = 'reports'
    path = event['path']

    reports = Reports::ReportsZipper.new(prefix, path)
    
    reports.download_and_compress_files

    zip_file_path = reports.zip_file_path

    zip_file = File.new(zip_file_path).read()

    lambda_response = {
        'headers': { 'Content-Type': 'application/zip' },
        'statusCode': 200,
        'body': Base64.encode64(zip_file).force_encoding('UTF-8'),
        'isBase64Encoded': true
    }

    return lambda_response

rescue Exception => e
    $logger.error("Error processing. Event: #{event}, Error: #{e.message}")
    { isBase64Encoded: false, statusCode: 400 }
end

Is there something I'm missing?

答案1

得分: 2

不要有别的内容。以下是翻译好的部分:

"Instead of using API Gateway to download a ZIP, look at putting the ZIP file into an Amazon S3 bucket, presign the ZIP file and get the presign URL.

Once that is ready - use a Service like Amazon SNS to send out a notification message with the presigned URL. Then users can download the ZIP from the Presigned URL in the notification message (see below).

This approach and implementation details are described in this AWS DEV article:

Create a photo asset management application that lets users manage photos using labels

UPDATE

Here is the app you build if you follow the instructions in the previous AWS link. For example, assume I want to get all images that are tagged Bird.

I select the tag in the app and click Download.

如何使用AWS Lambda和API Gateway下载ZIP文件

The app dynamically creates a ZIP of all images with this tag (there are 3 images with this tag as shown in the app). After a few mins - i get an email with the presigned URL.

如何使用AWS Lambda和API Gateway下载ZIP文件

When I click that - I get my ZIP with the images.

如何使用AWS Lambda和API Gateway下载ZIP文件

Note - if i click the link after the presigned ULR expires, I can no longer get the S3 object.

For more information about presign - read:

https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html"

英文:

Instead of using API Gateway to download a ZIP, look at putting the ZIP file into an Amazon S3 bucket, presign the ZIP file and get the presign URL.

Once that is ready - use a Service like Amazon SNS to send out a notification message with the presigned URL. Then users can download the ZIP from the Presigned URL in the notification message (see below).

This approach and implementation details are described in this AWS DEV article:

Create a photo asset management application that lets users manage photos using labels

UPDATE

Here is the app you build if you follow the instructions in the previous AWS link. For example, assume I want to get all images that are tagged Bird.

I select the tag in the app and click Download.

如何使用AWS Lambda和API Gateway下载ZIP文件

The app dynamically creates a ZIP of all images with this tag (there are 3 images with this tag as shown in the app). After a few mins - i get an email with the presigned URL.

如何使用AWS Lambda和API Gateway下载ZIP文件

When I click that - I get my ZIP with the images.

如何使用AWS Lambda和API Gateway下载ZIP文件

Note - if i click the link after the presigned ULR expires, I can no longer get the S3 object.

For more information about presign - read:

https://docs.aws.amazon.com/AmazonS3/latest/userguide/ShareObjectPreSignedURL.html

huangapple
  • 本文由 发表于 2023年6月22日 09:03:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76528042.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定