LoginSignup
2
4

More than 5 years have passed since last update.

Claudia.jsで画像ダウンロードAPIを作成

Last updated at Posted at 2017-03-14

概要

2016年11月にAPI GatewayでBinaryデータが扱えるようになりました。
Binary Data Now Supported by API Gateway

Claudia.jsのAPI Builderでも対応していたため、試しにClaudia.jsでS3に置いた画像ファイルをAPI経由でダウンロードできるようにしてみたいと思います。

コード

まずAPIBuilderの設定で、どのMIME-TYPEをバイナリとして扱うかを指定する必要があります。これはsetBinaryMediaTypesで行います。

import ApiBuilder from 'claudia-api-builder'

const api = new ApiBuilder()
api.setBinaryMediaTypes(['image/jpeg', 'image/jpg', 'image/png'])

各APIリソースの設定では、レスポンスのオプションでcontentHandling: ''CONVERT_TO_BINARY'' を指定する必要があります。このオプションを指定することにより、APIGatewayでbase64エンコーディングされた文字列がバイナリデータに変換されます。

api.get('/img', requestHandler, {
  success: {
    contentHandling: 'CONVERT_TO_BINARY',
  },
})

リクエストハンドラーの処理は以下のようになります。

const requestHandler = async () => {
  const params = {
    Bucket: 'bucketName',
    Key: 'images/sample01.jpg',
  }
  const data = await this.s3.getObject(params).promise()
  const response = new api.ApiResponse(data.Body, {
    'Content-Type': data.ContentType,
  }, 200)
  return response
}

動的にS3データのContent-Typeをレスポンスヘッダに指定しています。動的にResponseを返す場合はapi.ApiResponseのインスタンスを返す必要があります。

responseのbodyは、base64に変換しなくてもBufferのまま返せばClaudia.jsのAPIBuilderが自動でbase64に変換してくれます。

検証

この状態でデプロイし、テストしてみます。事前にS3のバケットを用意して適当な場所(images/sample01.jpg等)に画像ファイルを配置しておきます。

HTTPリクエストは以下のようにAcceptヘッダを指定する必要があります。

curl -H "Accept: image/jpg" "https://<id>.execute-api.ap-northeast-1.amazonaws.com/latest/img"  > /tmp/image.jpg

ダウンロードしたファイルをビューワー等で問題なく開くことができればOKです。

問題

画像がダウンロードできるようになったのでWebページのHTMLの<img>タグのsrcに指定して利用したいところですが、問題があります。Acceptヘッダに複数のMIME-TYPE("image/*"や、"image/png, image/jpg"等)を指定した場合、画像が正常にダウンロードできません。Claudia.jsのドキュメントにも以下のように書かれていますが、Acceptヘッダを複数指定した場合変換がうまく動作しないようです。

Similarly, although the documentation suggests that multiple content types can be specified in the Accept header for binary responses, it seems that this breaks the conversion. This makes the current implementation useless for browsers, which by default request complex Accept headers. This means that it’s currently not possible to use the API Gateway/AWS_PROXY integration to return images that can be just included into a web page using the img tag.

ブラウザのデフォルトの動作として、imgタグのHTTPリクエストではデフォルトでAcceptヘッダを複数指定するため、正常に画像を取得することができません。つまり、現状では<img>タグからは利用できないということになります。

終わりに

現状では<img>タグからは利用できませんが、こちらの問題がクリアされれば、Webページの画像APIとしてバリバリ利用できそうな気がします。

※サンプルコードはGithubに上げてます (https://github.com/gaishimo/claudiajs-image-downloader)

参照

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4