目次

概要

API Gateway & Lambda でバイナリレスポンスを返却する場合の覚え書き。

ポイントは以下の3点

  • Lambda のレスポンスで isBase64Encoded: True を指定しつつ、Base64エンコードされたデータを返却する
  • API Gateway の バイナリメディアタイプ で対象のコンテンツタイプを指定する
  • リクエスタから Accept ヘッダで対象のコンテンツタイプを受け取っていない場合は Base64デコードされない。
     ※Base64エンコードされたデータがそのまま返却される

注意)
 ただし、あまり大きな画像を返却するような処理はメモリ消費が大きい為、書くべきではない。
 Lambdaのレスポンスサイズ制限や費用も考慮する事。
 多分、バッチでS3に出力しておいて、API Gateway から呼ばれる Lambdaでは、期限付きの署名付きURLを発行するぐらいにしておく方が良い。

フォルダ/ファイル構成

/work
 /template.yml
 /src
  /index.py
  /sample1.png

 
・・・ cloudformationテンプレート
・・・ Lambdaソース格納用
・・・ Lambda本体(メインハンドラ)
・・・ 返却する画像

Lambda

./src/index.py

import base64


def handler(event, context):

  with open("sample1.png", "rb") as f:
    bytes_image = f.read()
    encoded_image = base64.b64encode(bytes_image).decode("utf-8")

  return {
    "statusCode": 200,
    "headers": {"Content-Type": "image/png"},
    "isBase64Encoded": True,
    "body": encoded_image
  }

CloudFormationテンプレート

[参考]
https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md

./template.yml

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31
Description: "バイナリデータを返却する API Gateway & Lambda"

Resources:
  ImageResponseApi:
    Type: AWS::Serverless::Api
    Properties:
      Name: ImageResponseApi
      StageName: Prod
      BinaryMediaTypes: 
        - "image/*"

  ImageResponseFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: ImageResponseFunction
      CodeUri: ./src
      Handler: index.handler
      Runtime: python3.6
      Events:
        GetRoot:
          Type: Api 
          Properties:
            RestApiId: !Ref ImageResponseApi
            Path: /
            Method: get 

Outputs:
  ImageResponseApiUrl:
    Value: !Sub "https://${ImageResponseApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
    Export:
      Name: ImageResponseApiUrl

デプロイ

確認

ブラウザからURLを直接叩いても、Acceptヘッダは付かないので注意が必要。

curl から Acceptヘッダ付きのリクエストを発行して確認。(レスポンスはバイナリなのでファイルに出力)

curl -H "Accept: image/png" --output test.png 対象のAPIのURL

もしくは、以下の様な簡単なHTMLで確認しても良い。

<!doctype html>
<html>
<img src="対象のAPIのURL">
</html>

トップ   差分 バックアップ リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-09-01 (日) 19:51:08 (1699d)