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