- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2019-09-01T11:42:19+00:00","","")
#author("2019-09-05T12:05:49+00:00","","")
#mynavi(AWSメモ)
#setlinebreak(on);
* 目次 [#m682af77]
#contents
- 参考
-- https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html
-- https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-payload-encodings.html
-- https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-controlling-access-to-apis.html
-- https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-template.html
-- https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessapi
-- https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
- 関連
-- [[AWS CloudFormationメモ]]
-- [[Lambda&API GatewayをCloudFormationで作成する]]
-- [[1つのAWS LambdaでSPA(CloudFront編)]]
* 概要 [#oc71e755]
#html(<div style="padding-left: 10px;">)
API Gateway & Lambda でバイナリレスポンスを返却する場合の覚え書き。
ポイントは以下の3点
- Lambda のレスポンスで isBase64Encoded: True を指定しつつ、Base64エンコードされたデータを返却する
- API Gateway の バイナリメディアタイプ で対象のコンテンツタイプを指定する
- リクエスタから Accept ヘッダで対象のコンテンツタイプを受け取っていない場合は Base64デコードされない。&br; ※Base64エンコードされたデータがそのまま返却される
#html(</div>)
// 概要 END
* フォルダ/ファイル構成 [#i6afbb5a]
#html(<div style="padding-left: 10px;">)
#html(<div style="border:1px solid #333; padding:10px; display: inline-block;">)
#html(<div style="display:inline-block;">)
/work
/template.yml
/src
/index.py
/sample1.png
#html(</div>)
#html(<div style="display:inline-block; padding: 0 30px; vertical-align: top;">)
・・・ cloudformationテンプレート
・・・ Lambdaソース格納用
・・・ Lambda本体(メインハンドラ)
・・・ 返却する画像
#html(</div>)
#html(</div>)
#html(</div>)
// フォルダ/ファイル構成 END
* Lambda [#mf82fa5a]
#html(<div style="padding-left: 10px;">)
./src/index.py
#mycode2(){{
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
}
}}
#html(</div>)
// Lambda
* CloudFormationテンプレート [#e9427fc1]
#html(<div style="padding-left: 10px;">)
[参考]
https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md
./template.yml
#myterm2(){{
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
}}
#html(</div>)
* デプロイ [#jf7890e1]
#html(<div style="padding-left: 10px;">)
参照: [[CloudFormation実行用のシェル]]
#html(</div>)
* 確認 [#u91f8f4f]
#html(<div style="padding-left: 10px;">)
ブラウザからURLを直接叩いても、Acceptヘッダは付かないので注意が必要。
curl から Acceptヘッダ付きのリクエストを発行して確認。(レスポンスはバイナリなのでファイルに出力)
#myterm2(){{
curl -H "Accept: image/png" --output test.png 対象のAPIのURL
}}
もしくは、以下の様な簡単なHTMLで確認しても良い。
#mycode2(){{
<!doctype html>
<html>
<img src="対象のAPIのURL">
</html>
}}
#html(</div>)