Serverless CLI を使って AWS Lambda + API Gateway から PNG を取得する方法 ( Accept ヘッダ無し )
2020-08-26
タイトル通り。
指定したURLのQRコードが欲しくて、API を作った。Accept
ヘッダ無し、というところがポイント。
つまり、単純な HTTP リクエストだけで画像を取れるようにしたかった。
目次
前提
$ serverless -v
Framework Core: 1.79.0
Plugin: 3.7.1
SDK: 2.3.1
Components: 2.34.6
$ node -v
v12.4.0
$ yarn -v
1.22.4
$
手順
プロジェクト作成
$ serverless create --template aws-nodejs -p qrcode-gen
$ cd qrcode-gen
$ yarn add qrcode
serverless.yml
service: qrcode-gen
provider:
name: aws
runtime: nodejs12.x
stage: dev
region: ap-northeast-1
functions:
qr:
handler: handler.qr
events:
- http:
path: qr/{url}
method: get
integration: lambda
request:
parameters:
paths:
url: true
response:
headers:
Content-Type: "'image/png'"
contentHandling: CONVERT_TO_BINARY
気持ちとして「レスポンスヘッダの Content-Type
が image/png
で、実際にバイナリが返却できれば良いよね?、というのを、愚直に実現する方法。
16行目 integration: lambda
を明示的に指定する。(指定しないと、 lambda_proxy
となってうまくいかない。)
これによって、 Accept
ヘッダ無しを実現。
また、 integration: lambda
の指定によって、22-24行目が指定可能になる。
22-23行目で、レスポンスヘッダの Content-Type
を image/png
に設定している。
24行目が、 Lambda から返却された Base64 のデータをバイナリ化する設定。
handler.js
'use strict';
const QRCode = require('qrcode')
module.exports.qr = async event => {
const url = await QRCode.toDataURL(decodeURIComponent(event.path.url))
// 先頭の "data:image/png;base64," をカットして返却 (Base64)
return url.substring(22)
}
これだけ。
qrcode
の toDataURL()
が埋め込みURIの形式でQRコードを生成してくれるので、先頭の情報を削って返却すれば完了。
結果
https://www.tacck.net
をURLエンコードしたものを渡してみる。
$ serverless deploy
$ curl https://XXXXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/dev/qr/https%3A%2F%2Fwww.tacck.net > tacck_qr.png
必要な時に動的にHTML内に埋め込めるようになるので、お手軽で便利。