[AWS SAM]REST APIのメソッドとLambda関数をN:1にするには?
はじめに
AWS SAMのテンプレートで、REST APIの複数メソッド(PUT/GET/POST/DELETEなど)に対して1つのLambda関数とする場合にどのように書くのか?
マネジメントコンソールであれば、用意したLambda関数を各APIに紐づけてあげるだけなのですが、なかなか情報がなかったのですがようやく分かりました。
REST APIのメソッドとLambda関数を1:1にする
以下、REST APIのメソッドとLambda関数を1:1にする場合の例です。
Resources:
ToDoCreateFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: todo/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
FunctionName: todo_create
Policies:
DynamoDBCrudPolicy:
TableName: !Ref TodoTable
Events:
ToDo:
Type: Api
Properties:
Path: /todo
Method: post
Layers:
- !Ref ToDoLayer
ToDoReadFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: todo/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
FunctionName: todo_read
Policies:
DynamoDBCrudPolicy:
TableName: !Ref TodoTable
Events:
ToDo:
Type: Api
Properties:
Path: /todo
Method: get
Layers:
- !Ref ToDoLayer
ToDoUpdateFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: todo/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
FunctionName: todo_update
Policies:
DynamoDBCrudPolicy:
TableName: !Ref TodoTable
Events:
ToDo:
Type: Api
Properties:
Path: /todo
Method: put
Layers:
- !Ref ToDoLayer
ToDoDeleteFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: todo/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
FunctionName: todo_delete
Policies:
DynamoDBCrudPolicy:
TableName: !Ref TodoTable
Events:
ToDo:
Type: Api
Properties:
Path: /todo
Method: delete
Layers:
- !Ref ToDoLayer
・・・
例のようにREST APIの複数メソッドで共通のLambda関数のコード(app.lambda_handlerでメソッドごとの分岐を行う)を使用するような場合、
REST APIのメソッドとLambda関数を1:1で構築することは疎結合の観点では良いかもしれませんが、パッケージサイズが膨大になるなど弊害があると思います。
単純にサイズが4倍になりますので、私の環境では、たいしたコード量、たいしたモジュール量ではないのに、
Lambda 関数「xxx」のデプロイパッケージが大きすぎて、インラインコード編集を有効にできません。ただし、関数を呼び出すことはできます。
となったり、開発のしにくさからもあまり1:1にはしたくないと考えています。
REST APIのメソッドとLambda関数をN:1にする
以下、REST APIのメソッドとLambda関数をN:1にする場合の書き方です。
Resources:
ToDoFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: todo/
Handler: app.lambda_handler
Runtime: python3.9
Architectures:
- x86_64
FunctionName: todo
Policies:
DynamoDBCrudPolicy:
TableName: !Ref TodoTable
Events:
# メソッドごとに追記↓
ToDoCreate:
Type: Api
Properties:
Path: /todo
Method: post
ToDoRead:
Type: Api
Properties:
Path: /todo
Method: get
ToDoUpdate:
Type: Api
Properties:
Path: /todo
Method: put
ToDoDelete:
Type: Api
Properties:
Path: /todo
Method: delete
# メソッドごとに追記↑
最後に
REST APIの各メソッドとLambda関数を1:1にするか、N:1にするか、システム全体で見てどちらが最善か選択すればよいと思います。
Lambda関数自体を別とすることでパフォーマンス向上はしますが、共通のモジュールを複数使っている場合や、共通処理が多い場合、関数を別とすることでパッケージサイズが大きくなるなどデメリットもあると思います。
比較的コード量が少なめであれば分けずに共通のコード、関数の方が良いのかな、と考えます。
Discussion