FastAPI×MongoDBを用いたAPI開発の手ほどき② 〜DB接続〜
はじめに
こんにちは。LIRIS株式会社で取締役兼エンジニアをしています田村です。
前回投稿した「FastAPI×MongoDBを用いたAPI開発の手ほどき① 〜環境構築〜」の続きを書いていきます。初めての方は是非前回分から見ていただければと思います。
今回は、FastAPIとMongoDBを接続し、実際にCRUD操作を実装します。
コードだけ見たいという方はこちらから取得してください。
想定読者
- PythonでWeb API開発したい、されている方
- FastAPIに興味のある方、数年使っている方
- パフォーマンス向上に興味のある方
フォルダ・ファイル構成
今回は、DBとの接続行いますので以下の構成でフォルダ、ファイルを作成します。
appフォルダ内にdbフォルダを作成し、dbフォルダ内にsession.pyを作成します。
また、appフォルダ内にconfig.pyを作成します。
fastapi-mongo-example/
├ app/
│ ├ db/
│ │ └ session.py
│ ├ .dockerignore
│ ├ logging.conf
│ ├ config.py
│ ├ main.py
│ ├ poetry.lock
│ ├ pyproject.toml
│ ├ start.sh
│ └ Dockerfile
├ .gitignore
└ docker-compose.yml
config.pyの作成
config.pyにはアプリケーションで利用する環境変数などをまとめます。
今回はDB接続に必要な情報をまとめます。
from pydantic import Field
from pydantic_settings import BaseSettings
class DBConfig(BaseSettings):
DB_USERNAME: str = Field(description="DBのユーザ名")
DB_PASSWORD: str = Field(description="DBのパスワード")
DB_HOST: str = Field(description="DBのホスト名")
DB_PORT: str = Field(description="DBのポート番号")
db_config = DBConfig()
Pydantic_settingsは環境変数を管理するのに便利です。
デフォルト値やバリデーション、説明書きなどを設定できますのでおすすめです。
docker-compose.ymlの内容変更
docker-compose.ymlのenvironmentの内容に、先程config.pyに記述した環境変数を追記していきます。
長くなるので、fastapiコンテナの設定のみ記載します。
version: "3.8"
services:
fastapi:
image: "fastapi:${TAG-latest}"
links:
- mongo
build:
context: ./app
dockerfile: Dockerfile
ports:
- 8000:8000
volumes:
- ./app:/app:cached
environment:
HOST: 0.0.0.0
PORT: 8000
LOG_LEVEL: info
LOGCONFIG: ./logging.conf
WORKERS: 1
APP_MODULE: main:app
DB_USERNAME: admin
DB_PASSWORD: password
DB_HOST: mongo
DB_PORT: 27017
tty: true
restart: unless-stopped
session.pyの作成
session.pyにはDB接続情報を記述していきます。
app/db/session.pyを作成し、以下のように記述します。
PythonでMongoDBを扱うのにpymongoライブラリを利用しています。
from urllib import parse
from config import db_config
from pymongo import MongoClient
from pymongo.database import Database
USER_NAME = parse.quote_plus(db_config.DB_USERNAME)
PASSWORD = parse.quote_plus(db_config.DB_PASSWORD)
HOST = db_config.DB_HOST
PORT = db_config.DB_PORT
MONGO_DATABASE_URL: str = f"mongodb://{USER_NAME}:{PASSWORD}@{HOST}:{PORT}"
client = MongoClient(MONGO_DATABASE_URL)
def get_db() -> Database:
"""DB取得
Returns:
Database: データべース
"""
db: Database = client.db
return db
main.pyの修正
APIをシャットダウンする時にDBのセッションも一緒に切断するように、main.pyに記述します。
@app.on_eventデコレータ
を用いてシャットダウン時の動作を定義しています。
from db.session import client
from fastapi import FastAPI
app = FastAPI(
title="FastAPI Sample",
)
@app.on_event("shutdown")
def shutdown_event():
client.close()
@app.get("/", status_code=200)
def root():
return "成功!"
DBにデータを登録してみる
エンドポイント追加
DBに接続できているか確認してみます。
main.pyに /box
のPOSTメソッドとGETメソッドを追加して動作確認します。
from db.session import client, get_db
from fastapi import FastAPI
app = FastAPI(
title="FastAPI Sample",
)
@app.on_event("shutdown")
def shutdown_event():
client.close()
@app.get("/", status_code=200)
def root():
return "成功!"
@app.post("/box", status_code=200)
def post_item_in_box(item: str):
# dbというデータベースを取得
db = get_db()
# データベースにデータを追加
result = db["box"].insert_one({"item": item})
return {"id": str(result.inserted_id)}
@app.get("/box", status_code=200)
def get_items_in_box():
# dbというデータベースを取得
db = get_db()
# データベースからデータを取得
items = db["box"].find()
# データを整形
results = [{"id": str(item["_id"]), "item": item["item"]} for item in items]
return results
"id"をstr型に変換していますが、これはMongoDBのデフォルトのIDがObjectIDという形式になっており、ObjectIDのままでは返せないので、strに変換しています。
ここの効率的な処理も今後紹介していきます。
動作確認
docker-compose up -d
でDockerコンテナを起動します。
http://localhost:8000/docsにアクセスして、Swagger UIが立ち上がっていれば下図のように表示されます。
先ほど追加した /box
のPOSTメソッドとGETメソッドが増えています。
まずはPOSTメソッドでデータを登録します。
- 緑の
/box
POSTメソッドをクリック - 右側に"Try it out"のボタンが表示されますので、そのボタンをクリック
-
item
欄に好きな文字列を入力 - 最後に下の青い"Execute"ボタンをクリック
これで記念すべきデータ第1号が登録されました。
本当に登録されているか確認しましょう。
GETメソッドを実行します。
- 青い
/box
GETメソッドをクリック - 右側に"Try it out"のボタンが表示されますので、そのボタンをクリック
- 最後に下の青い"Execute"ボタンをクリック
正常に処理が完了していれば、登録したitemが表示されます。
mongoexpressでDBを確認
mongoexpressというGUIツールを使うことで、APIを経由しなくても簡単にMongoDBの中身を確認できます。
第1回目でDockerの設定はしていました。
http://localhost:8081/にアクセスすると下図のように表示されます。
db
の"View"をクリックしてみると、先程作成した box
コレクションが表示されます。
MongoDBでは、RDBで言うところのテーブルに当たるものがコレクションです。
では、”View”をクリックすると先程登録したデータが入っていると思います。
MongoDBでは、RDBで言うところのレコードに当たるものがドキュメントになります。
※ mongoexpressを本番環境では利用せず、開発環境のみで利用するようにしましょう。
まとめ
今回実施したこと
- Pydantic_settingsを用いた環境変数管理
- MongoDBとの接続
- MongoDBの動作確認
- mongoexpressの紹介
ここまでのコードはこちらから取得できます。
次回は Pydantic
を使ったスキーマ作成を予定しています。
この記事を読んでみて何か学びが得られれば幸いです。
Discussion