###### tags: `卒業制作`
# バックエンド開発
> 「たびたび」のバックエンド側の情報共有用
> AWSのLambdaでPythonを書く!!自由に追記してね!!
## 記事とかの共有
[AWS SAMとRDSの接続](https://chariosan.com/2020/01/12/sam_rds_python/)
[AWS SAMのドキュメント](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/what-is-sam.html)
[Python+mysql-connector-python の使い方まとめ(Qiita)](https://qiita.com/valzer0/items/2f27ba98397fa7ff0d74)
[Python命名規則一覧(Qiita)](https://qiita.com/naomi7325/items/4eb1d2a40277361e898b)
## 不明点や調べることなどのメモ場所
* lambda マッピングテンプレート
## 使うツールとか技術
* Docker(ローカルでAPI Gatewayを起動するため)
* Python 3.8
* Git
* MySQL 5.*
* AWS SAM(ローカル開発とデプロイ)
* AWS API Gateway(リクエスト)
* AWS Lambda(プログラム)
* AWS S3(ストレージ)
* アルバムの画像保存
* AWS Cognito(認証)
* 独自認証(Email&PassWord)
* ソーシャルログイン(Google)
* Cognitoでユーザー登録時にトリガーでLambda実行してRDSのテーブルにユーザー情報を保存する
## Lambdaのローカル開発
### Git 運用メモ
* developブランチから新しくブランチを切る
* developにpushする
* developにmergeする
* apiキーとか公開してはダメなものに気を付ける
### ディレクトリ構成とURL設計
* SAMのディレクトリとAPIのURLを書く
### AWS SAMでのローカル開発環境構築
* 環境構築と使い方
[AWS SAM CLI 再入門](https://qiita.com/hayao_k/items/7827c3778a23c514e196)を見ると環境構築とコマンドについてある程度わかる
* gitとdockerが必要
Windowsは上記のQiita記事見ればできるはず
```
Mac版のbrewを使ったインストール
$ brew tap aws/tap
$ brew install aws-sam-cli
$ sam --version //バーション出ればOK
```
#### 実行方法
```
$ sam build // 全部ビルド(全部するので時間かかる)
$ sam build [Lambda関数名] // 単一ビルド
$ sam local invoke [Lambda関数名] // コマンド実行
$ sam local start-api // API GateWay 起動
```
### CloudFormationを書く(template.yaml)
* ローカルでAPI Gatewayを立てた時実行される
* これをもとにAWS本番環境にデプロイする
* 1つの関数で下のyamlを書くのでめっちゃ多くなる・・・どうしたもんか。
```
Resources:
TestFunction: #Lambda関数名
Type: AWS::Serverless::Function #Lambda使う宣言
Properties:
CodeUri: test_function/ #関数フォルダのパス
Handler: app.lambda_handler #実行する関数(ファイル名.関数名)
Runtime: python3.8 #ランタイム(言語)
Events:
HelloWorld:
Type: Api
Properties:
Path: /test #localhost:3000/test
Method: get #get,post
```
## LambdaとPythonのサンプル
[サンプルプログラム](https://github.com/matsukawa-s/lambda_sample)
* Lambda関数使うのに2つの引数は必要(event,context)
* eventの中身はいろいろ書いてる
* eventの中にget送信のパラメータやpost送信のデータが入ってる
### GETリクエスト処理
例:127.0.0.1:3000/getread/{id}
```
def lambda_handler(event, context):
# eventのpathParametersに入ってくる
id = event["pathParameters"]["id"]
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world",
}),
}
```
### POSTリクエスト処理
* データはjsonで送る
* HTTPヘッダーCORSをつけて送信する
* (よくわからないのでまた調べるけど、付けないとエラーでる)
```
Access-Control-Allow-Origin : *
```
例:127.0.0.1:3000/create
```
def lambda_handler(event, context):
# eventのbodyに入ってくる
# jsonパース
data = json.loads(event["body"])
id = data["id"]
name = data["name"]
job = data["job"]
return {
"statusCode": 200,
"body": json.dumps({
"message": "hello world",
}),
}
```
### RDS(MySQL)と繋ぐ
* mysql.connectorを使用する(他にもmysql用のライブラリはある)
mysql接続(connの接続部分はあとでLayer化して共通処理にする)
```
conn = mydb.connect(
# dockerからホストのmysqlに繋いでる
# 環境に合わせて変える
# host='host.docker.internal',
host=[ホスト]
port=[ポート番号:3306],
user=[ユーザー名],
password=[パスワード],
database=[データベース名:tabitabi_db]
)
# カーソル作成
# dictionary=Trueでカラム名をキーに辞書型で返ってくる
cur = conn.cursor(dictionary=True)
cur.execute("SELECT * FROM emp");
rows = cur.fetchall()
# カーソルとコネクションを閉じる
cur.close()
conn.close()
```
* returnでjson.dumpで射影の結果を入れて返すといい感じに返ってくる
```
return {
"statusCode": 200,
"body": json.dumps(rows),
}
```
### ライブラリと共通処理(Layer)
> ライブラリやmysqlの接続とか共通で使うものをまとめる為のもの
* レイヤー作成
```
$ mkdir [layer名]
$ touch layer名/requirements.txt
```
requirements.txt(ここにライブラリ名書く)
```
numpy
mysql-connector-python # mysqlコネクターライブラリ
```
### デプロイ
* template.yamlを元にデプロイする