API gateway経由でLambdaでFlaskアプリをZappaなしでデプロイ（忘備録）

# API gateway経由でLambdaでFlaskアプリをZappaなしでデプロイ
### はじめに
今回は、API gateway経由でLambdaにFlaskアプリをZappaなしでデプロイする方法を勉強してみました。

**Zappaなしでデプロイする利点として以下があげられます。**

:::note
・カスタマイズ性
・自分でリソースを設定するので、エラーが特定しやすい
:::

### 手順

#### ①アプリをローカルで作成

**ディレクトリ構成**
```
test ーー app.py
      |__ handler.py
```

**app.py**
```python
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return {"message": "Hello from Lambda!"}

@app.route('/hello/<name>')
def hello_name(name):
    return f'Hello, {name}!'
```
**handler.py**
```python
from app import app
import serverless_wsgi

def lambda_handler(event, context):
    return serverless_wsgi.handle_request(app, event, context)
```

必要なら、venvでapp.pyがflaskで動くか確認してみる。

#### ②packageディレクトリにLambdaにもっていくlibraryパッケージをZipする。

- packageディレクトリにパッケージをインストール

```
pip install flask serverless-wsgi  -t ./package
```
- packageディレクトリに移動して、パッケージをzip

Mac/Linux
```
cd package
zip -r ../deployment.zip .
cd ..
zip -g deployment.zip app.py handler.py
```
Windows PowerShell
```
cd package
Compress-Archive -Path * -DestinationPath ../deployment.zip
```
```Compress-Archive -Path```：pathを指定して圧縮処理をする
```*```：カレントディレクトリを指定
```-DestinationPath ../deployment.zip```：圧縮先を指定

```
# 上の階層に戻る
cd ..

# アプリ本体（app.py と handler.py）を ZIP に追加（Updateモード）
Compress-Archive -Path app.py, handler.py -Update -DestinationPath deployment.zip
```
#### ③Lambdaにzipファイルを送る
右上：関数の作成を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/da1a0013-2f0f-482b-8efe-7a798051f7a8.png)

1から作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/720b4892-c7d4-4784-b655-062b37b83968.png)

ロールは、とりあえずなので基本的な～で選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/43daf5a4-46ca-41e0-befd-ac8022cd5000.png)


アップロード元を押して、先ほどの作ったdeployment　ZIPファイルをアップロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/bd77cdfa-15d8-4d69-b907-ba413349ac12.png)

ハンドラ：handler.lambda_handlerに変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/1fbf71d6-0027-4df3-aa03-26e351268681.png)

認識されていなかった、コードが出てくる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/bc42b03d-4b1c-4cd3-b2b3-b16a46b617f3.png)

- Lambdaをテストします。
テストのタブをクリック⇒新しいイベントを作成⇒イベント名：test-flaskとする⇒イベントJSONに以下を張り付ける
```JSON
{
  "httpMethod": "GET",
  "path": "/",
  "headers": {},
  "queryStringParameters": null,
  "body": null,
  "isBase64Encoded": false
}
```
テストのオレンジボタンを押す
成功すると緑の　実行中の関数：成功　がでてくる
▼詳細で詳細が確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/6607afdc-95b4-4422-b6a2-3fe493a1ef09.png)

APIGatewayにてAPIを作成を押す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/5ab76b2d-3ea4-49e1-9c62-772fafbdf16b.png)

REST APIを選択。（HTTP APIよりも多機能）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/0da888f6-61a8-4f79-bf06-39628c16d9c4.png)

echo_flaskと名前をつける
エンドポイントタイプは、とりあえずリージョンで。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/9e37634d-bbd1-4d87-8683-2493f573c4c4.png)

うまくいくとこの画面。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/ff5d6149-88eb-4626-8173-164f1220b709.png)

メソッド作成をおすと以下画面
GETを選んで、Lambdaを選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/0a11b55c-823e-4973-a8ff-c4a18ad074ae.png)
Lambdaプロキシ統合を有効化。←重要
Lambdaで作った関数を選ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/c7a576b5-2fe1-4cf6-8de9-7bbe007df999.png)


APIをデプロイをする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/9ee90423-83bc-44b2-8da2-d214f061fbff.png)

ステージ名は、とりあえずdev
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/6f08d4b1-0b2b-4fc6-bec1-a56835d0306f.png)

URLを呼び出すをコピーしてブラウザに貼って接続
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/cd6202fe-df1d-4324-a606-64e277812da8.png)
 #### ④```/hello/<name>```のデプロイ
 リソースを作成を押してリソース名にhelloを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/5569fe51-59aa-4a67-954c-4e72af5847b5.png)
メソッドを作成を押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/1a1a61e4-463c-4615-b5b4-c3f2cabf49c9.png)
先ほどを同じようにLambdaプロキシ統合をオンにして、先ほどのLambdaを選ぶ

/helloを選択したまま、リソースを作成を押す。
今度は、リソース名：{name}として作成。
同様にメソッドを作成でLambdaプロキシ統合をオンにして、先ほどのLambdaを選んで、メソッドを作成を押す。
APIをデプロイでステージを新しくするなり、そのままでもどちらでもいいのでデプロイ。（ステージはVersionと同じような感じ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3967486/bd3cfcf0-0338-473d-bfdf-3bfaadd16c09.png)

検証にかなり時間使ったが、できてよかった～。