LoginSignup
4
0

はじめてのserverless deploy

Last updated at Posted at 2023-12-05

はじめに

この一年はバックエンドは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

おわりに

少しは慣れたような気がします!

4
0
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
4
0