はじめに
この一年はバックエンドはDocker+lambdaのserverless deployの構成をずっと触っていましたので、
簡単に振り返ってみたいと思います。
これまでにいくつか記事を投稿しています。
はじめてのserverless deploy
Rails+Reactでserverless deployに挑戦しましたが、ハンドラーやlambdaのアップロードサイズ制限などで苦戦しました。
-
Dockerイメージとlambda
当時挑戦していたのはDockerイメージをlambdaに載せてサーバレスデプロイする構成でした。
このイメージがlambdaのアップロードサイズの制限を超えているとエラーで引っかかります。
GoやPythonでは気にならなかったのですがRailsだと色々なファイルがあるのでapiモードで作成したプロジェクトをそのままイメージにすると引っかかります。 -
ハンドラー
API Gatewayから受け取ったリクエストをlambda関数に紐づける部分のことです。
調べても有益な情報をあまり得られず、社内で他の案件で使用している人に教えていただきました。
lambda.rb
require 'json'
require 'rack'
require 'base64'
$app ||= Rack::Builder.parse_file("#{__dir__}/config.ru").first
ENV['RACK_ENV'] ||= 'production'
module App
class Handler
def self.process(event:, context:)
puts event
body = if event['isBase64Encoded']
Base64.decode64 event['body']
else
event['body']
end || ''
puts body if body.present? && body.exclude?('password')
headers = event.fetch 'headers', {}
env = {
'REQUEST_METHOD' => event.fetch('httpMethod'),
'SCRIPT_NAME' => '',
'PATH_INFO' => event.fetch('path', ''),
'QUERY_STRING' => Rack::Utils.build_query(event['queryStringParameters'] || {}),
'SERVER_NAME' => headers.fetch('Host', 'localhost'),
'SERVER_PORT' => headers.fetch('X-Forwarded-Port', 443).to_s,
'rack.version' => Rack::VERSION,
'rack.url_scheme' => headers.fetch('CloudFront-Forwarded-Proto') { headers.fetch('X-Forwarded-Proto', 'https') },
'rack.input' => StringIO.new(body),
'rack.errors' => $stderr,
}
headers.each_pair do |key, value|
name = key.upcase.gsub '-', '_'
header = case name
when 'CONTENT_TYPE', 'CONTENT_LENGTH'
name
else
"HTTP_#{name}"
end
env[header] = value.to_s
end
begin
status, headers, body = $app.call env
headers.merge!({
'Access-Control-Allow-Origin': ENV['CLOUDFRONT_ADDRESS'],
'Access-Control-Allow-Credentials': true,
'Access-Control-Expose-Headers': 'Content-Disposition,X-Suggested-Filename',
'Content-Security-Policy': "default-src 'self'"
})
body_content = ""
body.each do |item|
body_content += item.to_s
end
response = {
'statusCode' => status,
'headers' => headers,
'body' => body_content
}
rescue Exception => exception
response = {
'statusCode' => 500,
'body' => exception.message
}
end
response
end
end
end
おわりに
少しは慣れたような気がします!