【aws/api gateway/lambda/s3】 api gateway ⇔ lambda ⇔ s3 で、動的に画像のresize railsから叩いてみる編
目次
前略
作ったresize apiをrailsから使う場合の設定 carrierwaveを使う前提でやる
画像保存カラム名は、image
railsの設定
今回は、content_image_controller を作成し resizeした画像を扱うだけの コントローラーを使う
view
任意のviewで
= image_tag(content_image_path(id: @hogehoge.id, resize_query: 500), alt: '画像サイズが大きすぎます。もう少し小さいサイズのアップロードをお願いします。')
controller
class ContentImagesController < ApplicationController def show hogehoge = HogeHoge.find(image_params[:id]) # ここでimage取ってきて image = ImageResizer.new(hogehoge.id, image_params[:resize_query]).get_image # ここでimageを返す send_data(image, disposition: "inline", type: file_type(hogehoge) ) end private def image_params params.permit(:id, :resize_query) end def file_type(hogehoge) "image/#{hogehoge.image.path.split('.')[-1]}" end end
画像取得部分
service層を作成し そこにおいた
- S3に画像があるかチェック
- なかったらAPI叩いてresizeした画像を取得
- どちらであっても、画像のデータを返す
今回は、エラーの場合は、エラーの画像を返すようにした
class ImageResizer def initialize(id, resize_query) @id = id @resize_query = resize_query @hogehoge = HogeHoge.find(id) end def get_image begin bucket = Aws::S3::Resource.new( access_key_id: Rails.application.secrets.aws[:access_key_id], secret_access_key: Rails.application.secrets.aws[:secret_access_key], region: 'ap-northeast-1' ).bucket(Settings.image.bucket) rescue # 仮にシステムエラーでS3に接続できない場合は、public/system-error.pngを返す open("#{Rails.root}/public/system-error.png").read end # 決まったパターンのURLなので、ここで作成 key = resized_file_name # 存在チェックし、あれば返答 return bucket.object(key).get.body.read if bucket.object(key).exists? # なければ、ここで、resizeした画像を要求 resized_image_body end private def resized_file_name "#{Settings.image_content.folder}/#{@id}/#{@resize_query}/#{@hogehoge.image.path.split('/')[-1]}" end def resized_image_body host_uri = URI.parse(Settings.image_resize_api.url) http = Net::HTTP.new(host_uri.host, host_uri.port) http.use_ssl = true uri = URI.parse("#{Settings.image_resize_api.url}/#{Settings.image_content.bucket}/#{Settings.image_content.folder}/#{@id}/#{@resize_query}/#{@hogehoge.image.path.split('/')[-1]}") req = Net::HTTP::Get.new(uri) req['Content-Type'] = "image/#{@hogehoge.image.path.split('.')[-1]}" req['Accept'] = "image/#{@hogehoge.image.path.split('.')[-1]}" res = http.request(req) case res when Net::HTTPSuccess res.body else # システムエラーのときは、public/too-big.pngを返す open("#{Rails.root}/public/too-big.png").read end end end