環境
API Gateway
Lambda(Python)
AWS CDK(typescript)
概要
zxy方式のラスター画像を会得しleafletなどでフロントに表示したかったため、ラスター画像を送信する以下のようなAPIを、AWSCDK, API GatewayとLambdaを用いて作っていた。
"https://lusterapi.ap-northeast-1.amazonaws.com/v1/{z}/{x}/{y}",
こちらのAPI URLにパラメータ入れてアクセスすると以下のように画像が出てくれると嬉しかった。
しかし以下のように、API URLにアクセスしても画像が表示されない問題が発生してしまった。
エラーの原因
このURLについてPythonのRequestでは取れているため、API自体が何も返していないわけではないことがわかった。
url="https://lusterapi.ap-northeast-1.amazonaws.com/v1/{z}/{x}/{y}"
Request.get(url)
さらに帰ってきているレスポンスの内容を確かめるとバイナリデータであり、base64エンコードをすると無事保存もできた。
以下確認とbase64エンコードのPythonコード。
import requests
import base64
z='任意の値'
x='任意の値'
y='任意の値'
url = f"https://lusterapi.ap-northeast-1.amazonaws.com/v1/{z}/{x}/{y}"
response = requests.get(url)
# レスポンスがバイナリデータであることを確認
if response.content:
# バイナリデータをBase64エンコード
encoded_data = base64.b64encode(response.content)
# Base64エンコードされたデータをデコードして画像として保存
with open('output.png', 'wb') as f:
f.write(base64.b64decode(encoded_data))
else:
print("No response data received.")
つまり、Base64エンコードされた画像をレスポンスボディとして返す必要がある。
解決策
調べてみると以下のように、AWSコンソール上でのバイナリタイプ変更の記事がいくつかヒットしたんですが、AWSCDKでの変更記事が全然見当たらなかった、、。
ApiGateway + LambdaのExpressで画像も配信したら表示されなかったのでその時の対応メモ画像のヘッダ…
概要API GatewayとLambdaでS3にある画像を返却するクライアント側からは単にURLにアクセスしたら画像が表…
どうにか公式やchatGPT参照しながら以下の解決方法を発見。
AWSCDKのコードに binaryMediaTypes: [‘*/*’] を追加するだけでよかったみたい。
// API Gateway RestAPIの作成
const nameRestApi ="Luster API";
const restApi = new aws_apigateway.RestApi(this, nameRestApi, {
restApiName: `Luster_API`,
binaryMediaTypes: ['*/*'], // ここに追加
deployOptions: {
stageName: 'v1',
},
});
//API Gatewayにリクエスト先のリソースを追加
let restApiLuster = restApi.root.addResource('{z}');
restApiLuster = restApiLuster.addResource('{x}');
restApiLuster = restApiLuster.addResource('{y}');
//リソースにGETメソッド、Lambda統合プロキシを指定
restApiLuster.addMethod(
'GET',
new aws_apigateway.LambdaIntegration(fnc)
);
また、APIに紐づくlambda内のレスポンス設定も以下のようにbase64に設定しておく必要もあるため変更。
# header情報
headers = {
'Content-Type': 'image/png',
'Access-Control-Allow-Origin': '*'
}
# レスポンス
res = {
"statusCode": 200,
"headers": headers,
'body': base64.b64encode(open(outpng, 'rb').read()).decode('utf-8'),
'isBase64Encoded': True
}
これらの変更を適用した後、ブラウザのURLバーにAPI URLを直接入力すると、無事画像が表示された!!