Open1
API Gateway (HTTP API)+ Lambda (node-canvas)ハマりポイント達
忘れそうなのでとりあえずスクラップブックに。
node-canvasは2.8.0
lambdaはnode14.x
canvas2.8.0をlambdaで動かすまで
- node-canvasはネイティブなライブラリを参照する。かつnpm i canvasする環境に応じてprebuildされたライブラリがnode_modules/canvas/build/Release に格納される(ので、linux環境(WSL環境でもよかった)でnpm i して、lambdaにdeployすれば動きそう・・・だが動かない。
- どうやらこれは最新版のprebuildライブラリが、lambdaの実行環境のamazonlinux2のlibの配置や、バージョンがミスマッチなせい
- よくある手法としてはバージョンを下げる or コピーをするようにnpmのスクリプトをハックして実行する、だがこれは悔しいので正面から解決してみた
dockerのamazonlinux2をpull、その中で作業
- まずlib64/ から libblkid.so.1 libmount.so.1 libuuid.so.1 をnode_modules/canvas/build/Release にコピー
- yumでビルド系のプログラムをinstall (make gcc wget zlib-dev あたり)
- libpng1.6.37のソースコードを持ってきてビルド(これをしないと、zlibのバージョンが合わなくて動かない amazonlinux2で使われているzlibが古いのが問題なのだが、なんで古いままなんだろう・・・?)
- ビルドしたlibpng16.so.16を node_modules/canvas/build/Releaseにコピー
- libz.so.1もlib64/から一応上書き(これは必要か不明)
以上を入れたやつをlambda_layerにデプロイ
API Gateway (HTTP API)から結果をGET
これもはまったので注意。
ポイントは
- base64Encodeが必要
- canvasでのbase64エンコードはちょっと癖がある
の2点。
node-canvasの出力をbase64エンコード
canvas.toDataURL("image/png")の結果がbase64エンコードされている。
されているが、若干余分なデータ("data:image/png;base64, ")が先頭についてくる。
ので、
const dataRaw = canvas.toDataUrl("image/png")
const data = dataRaw.split(",")[1]
callback(
null,
{
statusCode: 200,
headers: {
"Content-Type": "image/png"
},
isBase64Encoded: true,
body: data
}
)
てな感じで値を返せばOK.
ここまでやっておけば、特に設定をすることもなく、API Gatewayはバイナリを返してくれる。