AWS Lambdaのご紹介

# はじめに
株式会社OMJテクノソリューションズ Advent Calendar 2023 21日目の記事です。

こんにちは、suenryuです！

今回はAWSのサーバーレスのサービスをご紹介！

いくつかのサービスがある中でも代表的な**AWS Lambda**を取り上げます！

# AWS Lambda
![lambda.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571908/d9340bd7-67af-8b1b-c8b8-87f99c366bd8.jpeg)
AWS Lambdaはサーバーレスのサービスで、OS、ミドルウェアなどのインフラを気にせずに、アプリケーション開発ができるサービスです。

AWS Lambdaでコードを書いてしまえば、実装もテストも簡単にできてしまいます。

他のAWSサービス使用には**boto3**というライブラリをインポートすればよく、
連携するさいも各サービスのコンソールから紐づけで比較的簡単。

対応言語も**Python, Java, Nodejs**など幅広く、随時ランタイムも更新されています。

:::note warn
AWS Lambdaから使用できる他のAWSサービスはアップデートによって変動します。
使用する際は公式ドキュメントを確認して下さい。
:::

# AWS Lambdaを使用したアーキテクチャ例
実際にAWS Lambdaを使用したサーバレスアーキテクチャの例をご紹介します。

![api.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571908/8ac9166a-a566-aa2d-e784-63d93ef4090e.jpeg)

上記の画像は**Web API**のアーキテクチャです。
API Gatewayと連携することでWeb APIとして公開することができます。

上記のサーバレスアーキテクチャがどのような流れになるのか、必要な用語も含め説明します。

## ①トリガー
**トリガー**とは**AWS Lambdaを呼び出すAWSサービス**のことです。

画像でいうと、**API Gateway**がそれにあたります。
 
API Gatewayにリクエストが送られ、API Gatewayに紐づいているAWS Lambdaが呼びだされます。

API Gatewayのほかにも**DynamoDB**や**Amazon Cognito**など様々なAWSサービスがトリガーになります。

:::note warn
2023年12月現在、すべてのAWSサービスをトリガーにすることはできません。
こちらに関しても公式ドキュメントを確認してください。
:::

## ②イベント
**イベント**とは**トリガーからAWS Lambdaに渡されるJSONデータ**のことです。

AWS Lambdaの関数を作成した際、初期のコードは以下のようになっています。(Python)
```python:lambda_function.py
import json

def lambda_handler(event, context):

    return {
        'statusCode': 200,
        'body': json.dumps("Hello from Lambda!")
    }
```

lambda_handlerの第一引数にある**event**にトリガーからのJSONデータが入ってきます。

このJSONデータの中身はトリガーによって多種多様で、このデータを使って処理を進めていきます。

以下に例として、API Gatewayのプロキシ統合のJSONデータを掲載します。
```json:API Gateway(proxy)
{
  "resource": "/",
  "path": "/",
  "httpMethod": "GET",
  "requestContext": {
      "resourcePath": "/",
      "httpMethod": "GET",
      "path": "/Prod/",
  },
  "headers": {
      "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
      "accept-encoding": "gzip, deflate, br",
      "Host": "70ixmpl4fl.execute-api.us-east-2.amazonaws.com",
      "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36",
      "X-Amzn-Trace-Id": "Root=1-5e66d96f-7491f09xmpl79d18acf3d050",
  },
  "multiValueHeaders": {
      "accept": [
          "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
      ],
      "accept-encoding": [
          "gzip, deflate, br"
      ],
  },
  "queryStringParameters": null,
  "multiValueQueryStringParameters": null,
  "pathParameters": null,
  "stageVariables": null,
  "body": null,
  "isBase64Encoded": false
}
```


## ③関数
**関数**とは**AWS Lambdaで作成した関数そのもの**です。

画像でいうところの**AWS Lambda**です。

関数ではメインの処理をコードで実装していきます。

基本的にAWS Lambdaで他のAWSサービスを使用するには**boto3**というライブラリを使用します。

例えば、DynamoDBからデータを取得するとしたら、
```python:get_item.py
import boto3

dynamodb = boto3.client('dynamodb')

def lambda_handler(event, context):
    """user_idが1のユーザーの情報を取得
    """
    response = dynamodb.get_item(
        TableName='sample_table',
        Key={
          'user_id': {'N': '1'}
        }
    ).get('item')

    return response

    """出力例
        {
          "user_id": {"N": "1"},
          "created_at": {"N": "1689000"},
          "user_name": {"S": "Hoge Tarou"}
        }
    """
```
というような形になります。

この**トリガー、イベント、関数**がAWS Lambdaではかなめになってくる要素です。
もし開発で使用する際に役立てていただけたら幸いです。

# AWS Lambdaのメリット・デメリット
サーバーレスサービスのAWS Lambdaですが、簡単に効率できる反面、デメリットも存在します。

## まずは良い点からご紹介！

### インフラを気にしなくていい
冒頭にも記載しましたが、AWS LambdaはOSなどのインフラを気にする必要がなくアプリケーションの開発に注力できる点がよいところです。

### アーキテクチャを柔軟に組める
こちらも記載していますが、AWS Lambdaは他のAWSのサービスとの連携ができるため、様々なアーキテクチャを組み立てることができます。

IoTデバイスや、データベース、通知フローなども組めて柔軟な対応ができます。

### バージョン管理やエイリアス設定ができる
![名称未設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/571908/30ed60ee-9bee-85cc-f738-36ef742c9a9d.gif)
AWS LambdaはGithubのようなバージョンを管理する機能があります。

この機能を使うことで、本番やテストで環境を分ける際にはそれぞれの環境に影響させることなく、比較的安全に修正などに取り組めます。

また、エイリアスの設定も可能で、各環境ごとにエイリアスを設定することで、修正による紐づけをAWS Lambdaに集約することもできます。

## 逆に微妙な点...

### 最長実行時間が15分
AWS Lambdaの最長実行時間は15分に制限されています。

基本的なものであれば問題ありませんが、バッチ処理など、時間がかかる処理についてはタイムアウトになっていしまう恐れがあるため注意が必要です。

### 一つの関数で複数のAWSサービスを使うのは危険
AWSのサービスにはデータベース以外にもS3などのストレージサービスがあります。

AWSサービスは相互にトランザクションなどを補完しているわけではないため、異常時の対処などが難しくなってしまいます。

### ログの管理
AWS LambdaではCloudWatchでのモニタリングをする必要があります。

料金が高いため、不要な出力をしないようにしたりする必要があります。

# まとめ
今回はAWSのサーバーレスサービス、AWS Lambdaについて紹介いたしました！

サーバーレスサービスとしていい面もありつつ、制限がかかるため万能ではありませんが、要件によっては最善な場合もあります。

状況によって使い分けていくのが大事ですね！

ではみなさん、よきAWSライフを！


:::note info
最後にAWS Lambdaの開発に有用なライブラリをいくつかご紹介します。

AWS Lambda Powertools: AWS Lambdaの開発をよりよくするライブラリ
https://docs.powertools.aws.dev/lambda/python/latest/

Boto3 DynamoDB Types: DynanmoDBのデータ変換を容易にしてくれるライブラリ
https://boto3.amazonaws.com/v1/documentation/api/latest/_modules/boto3/dynamodb/types.html
:::