Djangoサーバレス環境構築してみた
概要
Djangoとサーバレス学習のため、その組み合わせで環境構築してみました。
ゴール
SAMCLIでローカルからLambda起動、Djangoで作成したAPIのレスポンスが返ること
Djangoって??
フルスタックに使用できるpythonのフレームワーク。
Webアプリでよく使われる「ユーザー認証」「管理画面」「データベース(O/Rマッパー)」「フォームの作成・検証・処理」「キャッシュ機能」など機能が揃っている。
ほとんど設定せずに備え付けのものでアプリ開発完結してしまうイメージ。
やってみる
前提
- AWSアカウントは作成、ローカルと連携済み
(ローカルで試すだけなのでdeployスキップすればなくてもOK) - python3とpipのインストール済み
- sam-cliがインストールされていること
Djangoプロジェクトの作成
# プロジェクトディレクトリを作成
mkdir myproject
# プロジェクトディレクトリに移動
cd myproject
# 仮想環境を作成
python -m venv venv
# 仮想環境を有効化
# Windowsの場合
venv\Scripts\activate
# macOS/Linuxの場合
source venv/bin/activate
Djangoのインストール
pip install django
#プロジェクトの作成
django-admin startproject myproject .
上記フォルダが作成される。
実際に動くか確認してみる。
# Djangoローカルサーバー起動
python manage.py runserver
ターミナル内、下記URLを押下。
上記画面が出ればDjangoの立ち上げは成功
Djangoの簡易サーバーみたいなものでローカルでは立ち上がる。(runserverコマンドにより)
実際運用の際、簡易サーバーは使わない
Source : https://docs.djangoproject.com/en/2.2/intro/tutorial01/#the-development-server
Djangoでデフォルト作成されるファイル
作成されるファイルたち
- settings.py
- urls.py
- asgi.py
- wsgi.py
- manage.py
上記がデフォルトで作成される。それぞれ役割説明。。
1.settinngs.py
Djangoプロジェクトの設定ファイル.
2.urls.py
Djangoプロジェクト全体のURLの定義(エンドポイント定義)
サーバレスではなくてもいいのかも。APIGatewayがルーティングしてくれるため
3.asgi.py,wsgi.py
Gunicorn(WSGI)もUnivorn(ASGI)もPythonウェブアプリケーションをウェブサーバーと連携させるために必要なもの。
アプリとWebサーバの間に入って色々やってくれるインターフェース的な役割。
サーバレスではなくてもいいのかも。サーバはAWS管理のもの使用するため。
4.manage.py
Djangoプロジェクトに対する操作を行うための様々なコマンドラインが定義されているファイル
上記ファイルたちはconfigディレクトリとしてまとめると良いかも
Djangoでアプリ作成していく場合
python manage.py startapp myapp
myappのとこに任意のディレクトリ名つけて実行。
作成されたディレクトリ内を一つのアプリ、機能単位で開発していく。(詳細は割愛)
SAMの導入、サーバレスに
SAMテンプレートの作成
先ほど作成したフォルダ内にtemplate.ymlファイルを作成
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: A simple Django app
Resources:
DjangoFunction:
Type: AWS::Serverless::Function
Properties:
Handler: myproject.test.lambda_handler
Runtime: python3.10
CodeUri: .
MemorySize: 128
Timeout: 30
Environment:
Variables:
DJANGO_SETTINGS_MODULE: myproject.settings
Events:
Api:
Type: Api
Properties:
Path: /{proxy+}
Method: ANY
Outputs:
ApiUrl:
Description: "API Gateway endpoint URL for Prod stage"
Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/"
これでLamdaとApiGatewayが起動
一旦上記ファイルをコピペ。
正しくDeployできるか確認(一応。。)
sam build
#デプロイコマンド
sam deploy --guided
S3、CFスタックは任意の名前で作成。
デプロイ後、自身のマネジメントコンソールから内容が反映されているかを確認
APIGatewayはLambdaプロキシ統合にしておく。
*Lambdaプロキシ統合
APIGatewaがLambdaとデータフォーマットを気にせずリクエスト、レスポンスのやりとりができるようになる。
参照:https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html
Lambda実装してみる
myprojectフォルダ内にtest.pyの作成。
ただresponse返す簡単なもの。
template.yml内にはHandlerとしてtest.pyのHandlerを指定。
*Lamda_handler
→ Lamdaのエントリーポイント。関数の構造は引数にeventとcontextを渡す形で統一。
ローカルでSAMの起動
sam build
sam local invoke
上記コマンド実行でローカルLamda起動。
無事出力されていることを確認!
ちょいと感想
サーバレスにすると、Djangoのフレームワークとしての恩恵が全然活用しきれない気がする。
ソース文献も非常に少なかった。
かなり蛇行して、最終的にほぼただのLambdaの実装になってしまった。。
組み合わせとして選ぶメリットはほぼないのではと感じた。。