Lambda のハンドラを Ruby のクラスで書く

AWS SAM で sam init を実行して作られるファイルは、Lambda のハンドラが関数で書かれている。

def lambda_handler(event:, context:)
  # ...
end

ハンドラをクラスで書きたい。

理由としては、1 つのリポジトリに複数の Lambda ハンドラが存在する状況で、各ハンドラの spec を書く時に不都合があった。 spec 内で require_relative "path/to/app" と記述すると、複数の spec を実行した時に lambda_handler が切り替わらない。

そもそもリポジトリを分割するべきとか、spec の書き方が悪い、という意見もあるだろう。とにかくクラスで書きたい。

最小構成だと以下のような書き方になる。

hello_world/app.rb:

require "json"

module HelloWorld
  class Handler
    def self.process(event:, context:)
      {
        statusCode: 200,
        body: {
          message: "Hello World!",
        }.to_json,
      }
    end
  end
end

template.yaml:

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.HelloWorld::Handler.process
      Runtime: ruby2.7
      Events:
        HelloWorld:
          Type: Api
          Properties:
            Path: /hello
            Method: get

Handlerapp.lambda_handler から app.HelloWorld::Handler.process に変わるのがポイント。

参考

© 2023 暇人じゃない. All rights reserved.