要約
- Lambdaの呼び出しペイロード制限は6MBだが、バイナリデータを返却する場合は大体4.5MBまでのデータしか返せない
- Lambdaでバイナリデータを返却する場合はbase64にエンコードする必要があるため
Lambdaのペイロードの制限
Lambdaでは呼び出しペイロード1は6MBまでという制限が付いている2。
呼び出しペイロード (リクエストとレスポンス): リクエストとレスポンスにそれぞれ 6 MB (同期)
引用元: https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-limits.html
しかし、5MB弱のバイナリデータ(画像ファイルとか)を返却しようと思ってもできない。
この後の項で実験する。
Lambdaでバイナリデータを返却するWeb APIを実装する
概要
Lambda(関数URL)を用いて、画像を取得できるWeb APIを実装した。
エンドポイント/image
にGETリクエストしたとき、クエリパラメータname
にファイル名を指定すると、そのファイルを取得する。
ファイルはS3バケットから取得する。
Lambdaの仕様として、バイナリデータを返却する場合はbase64にエンコードする必要がある点に留意3。
注: バイナリデータの場合は、Lambda 関数の出力で、;isBase64Encoded プロパティを true に設定する必要があります。body プロパティには、base64 でエンコードされたバイナリメディアも含まれている必要があります。詳細については、「API Gateway における REST API のバイナリメディアタイプ」を参照してください。
引用元: https://repost.aws/ja/knowledge-center/api-gateway-binary-data-lambda?utm_source=chatgpt.com
ソースコード
import json
import boto3
import base64
from botocore.exceptions import ClientError
s3_client = boto3.client('s3')
BUCKET_NAME = 'bucket-name'
def lambda_handler(event, context):
image_name = event.get('queryStringParameters', {}).get('name', None)
response = s3_client.get_object(Bucket=BUCKET_NAME, Key=image_name)
image_data = response['Body'].read()
# 重要: Lambdaでバイナリデータを返す際はbase64へのエンコードが必須
encoded_image_data = base64.b64encode(image_data).decode('utf-8')
return {
'statusCode': 200,
'headers': {
'Content-Type': 'image/jpeg',
},
'body': encoded_image_data,
'isBase64Encoded': True,
}
配置するバイナリデータ
画像をS3バケットに2つ配置する。
4.6MBと4.8MBのファイルサイズを持つJPEG形式の画像ファイル。
実装したWeb APIからバイナリデータの取得を試みる
4.6MBのバイナリデータを取得する。
成功する。
$ curl --dump-header - "https://foobarfoobarfoobar.lambda-url.ap-northeast-1.on.aws/?name=dummy_image_4p6MB.jpg"
HTTP/1.1 200 OK
Date: Tue, 11 Mar 2025 16:17:49 GMT
Content-Type: image/jpeg
Content-Length: 4600000
Connection: keep-alive
x-amzn-RequestId: 8b5150ef-9378-458e-b060-4d3f130b89e2
X-Amzn-Trace-Id: Root=1-67d0622c-3c8559fe06e620ef7b853e7f;Parent=727baee9259e2775;Sampled=0;Lineage=1:4b1c4ed4:0
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
4.8MBのバイナリデータを取得する。
失敗する。
$ curl --dump-header - "https://foobarfoobarfoobar.lambda-url.ap-northeast-1.on.aws/?name=dummy_image_4p8MB.jpg"
HTTP/1.1 502 Bad Gateway
Date: Tue, 11 Mar 2025 16:17:58 GMT
Content-Type: application/json
Content-Length: 21
Connection: keep-alive
x-amzn-RequestId: 2a26a20f-e58d-49a3-9eca-ae596b0cf22a
X-Amzn-Trace-Id: Root=1-67d06234-214cf04e5aed8a96244936b2;Parent=1fbc00920a520653;Sampled=0;Lineage=1:4b1c4ed4:0
Internal Server Error
なぜ失敗するか
返却時にbase64へエンコードを行うことでデータのサイズが増え、ペイロード制限に抵触しているから。
base64へエンコードを行うと元のサイズから約1.33倍に増える。
Lambdaのペイロード制限が6MBなので、6/1.33 ≒ 4.51MB程度のバイナリデータしか返せないということになる。
4.6MBのバイナリデータ取得には成功したので、多少ブレは出ると思われる。