Serverless CLI を使って AWS Lambda + API Gateway から PNG を取得する方法 ( Accept ヘッダ無し )

タイトル通り。

指定した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-Typeimage/png で、実際にバイナリが返却できれば良いよね?、というのを、愚直に実現する方法。

16行目 integration: lambda を明示的に指定する。(指定しないと、 lambda_proxy となってうまくいかない。)

これによって、 Accept ヘッダ無しを実現。

また、 integration: lambda の指定によって、22-24行目が指定可能になる。

22-23行目で、レスポンスヘッダの Content-Typeimage/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)
}

これだけ。

qrcodetoDataURL() が埋め込み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

https://www.tacck.net

必要な時に動的にHTML内に埋め込めるようになるので、お手軽で便利。

tacck
  • tacck
  • 札幌のソフトウェアエンジニア。
    インフラ・バックエンド・フロントエンドと、色々やります。

    初心者・若手向けのメンターも希望あればお受けします。

    勉強会運営中
    * ゆるWeb勉強会@札幌
    * スマートスピーカーで遊ぼう会@札幌

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください