1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

ローカル API Gateway + Lambda (SAM CLI) + MySQL(Docker)環境構築方法メモ

Posted at
  • ローカル環境でAPI Gateway + Lambda + MySQL構成の開発環境を構築する方法についてメモする。

事前準備

  • 下記要素をインストールしておく。

    • SAM CLI
    • Docker, docker-compose
  • SAM プロジェクトを作成する。

    • ひな形作成

      sam init
      

      ※ランタイムはPython3.9を選択する

      ※Hello World Exampleを利用する

構成

project
├─start.sh
├─sam-app
│  ├─template.yaml
│  ├─env.json

......
│  └─hello_world
│    └─app.py   
│    └─requirements.txt 
└─db
    ├─docker-compose.yml
    ├─initdb.d
    |	└─init.sql   
	├─db      
    │  ├─data
    │  └─my.cnf
    └─mysql
        └─data

コード

db

  • docker-compose.yml

    • test_dbDBを立ち上げる
    • initdb.dディレクトリ配下の「.sql」ファイルを実行する
    version: "3.3"
    networks:
      container-link:
        name: docker.internal
    services:
      db:
        image: mysql:5.7
        container_name: db
        environment:
          MYSQL_ROOT_PASSWORD: rootpass
          MYSQL_DATABASE: test_db
          MYSQL_USER: mysqluser
          MYSQL_PASSWORD: mysqlpass
        networks:
          - container-link
        volumes:
          - ./db/data:/var/lib/mysql
          - ./db/my.cnf:/etc/mysql/conf.d/my.cnf
          - ./initdb.d:/docker-entrypoint-initdb.d
        ports:
          - 3308:3308
        command: --port 3308
        tty: true
    
  • initdb.d/init.sql

    • test_tableテーブルを作成し、初期データを登録する
    CREATE TABLE `test_db`.`test_table` (
      `seq` INT NOT NULL AUTO_INCREMENT,
      `name` VARCHAR(45) NULL,
      `age` INT NULL,
      PRIMARY KEY (`seq`));
    
    INSERT INTO `test_db`.`test_table` (`name`, `age`) VALUES ('Tanaka Taro', '20');
    INSERT INTO `test_db`.`test_table` (`name`, `age`) VALUES ('Yamada Jiro', '30');
    

sam-app

  • app.py

    • MySQLdb.test_db.test_tableからのデータ取得結果を返却する
    import json
    import mysql.connector
    import os
    def lambda_handler(event, context):
        # MySQLからデータ取得
        sql = "select * from test_table;"
        # 接続先情報は環境変数から読み込む
        conn = mysql.connector.connect(
            host = os.environ['MYSQL_HOST'],
            port = os.environ['MYSQL_PORT'],
            user = os.environ['MYSQL_USER'],
            password = os.environ['MYSQL_PASSWORD'],
            database = os.environ['MYSQL_DATABASE']
        )
        cur = conn.cursor(dictionary=True)
        cur.execute(sql)
        results = cur.fetchall()
        cur.close()
        conn.close()
    	# レスポンスボディ生成
        user_list = []
        for result in results:
            user_list.append({
                    "name":result["name"],
                    "age":result["age"]
                }
            )
        response_dict = {}
        response_dict['total'] = len(user_list)
        response_dict['items'] = user_list
        
        return {
            "statusCode":200,
            "body":json.dumps(response_dict)
        }
    
  • requirements.txt

    • MySQLコンテナ接続のためのmysql-connector-pythonを追加する
    requests
    mysql-connector-python
    
  • template.yaml

    • 環境変数読み込み用に以下を設定する
    ...
    Globals:
      Function:
        Timeout: 3
        Environment:
          Variables:
            MYSQL_HOST: MYSQL_HOST
            MYSQL_DATABASE: MYSQL_DATABASE
            MYSQL_PORT: MYSQL_PORT
            MYSQL_USER: MYSQL_USER
            MYSQL_PASSWORD: MYSQL_PASSWORD
    
  • env.json

    • DB接続情報を記述する
    {
        "Parameters": {
            "MYSQL_HOST":"db",
            "MYSQL_DATABASE":"test_db",
            "MYSQL_PORT":3308,
            "MYSQL_USER":"mysqluser",
            "MYSQL_PASSWORD":"mysqlpass"
        }
    }
    

その他

  • start.sh

    • 起動用スクリプト
    # DB起動
    cd db
    docker-compose up -d
    # アプリ起動
    cd ../sam-app
    sam build --use-container
    sam local start-api --docker-network docker.internal --env-vars env.json
    

動作確認

  • 以下のコマンドを実行する

    bash start.sh
    

    ※MySQLコンテナ起動(テーブル作成+初期データ登録) → SAM起動が行われる

  • 以下のリクエストを実行する

    GET /hello HTTP/1.1
    Host: 127.0.0.1:3000
    

    以下のレスポンスが返却される

    {
        "total": 2,
        "items": [
            {
                "name": "Tanaka Taro",
                "age": 20
            },
            {
                "name": "Yamada Jiro",
                "age": 30
            }
        ]
    }
    
1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?