概要
LitestarのWebAPIのシンプルなサンプルコードを紹介します。
コード一式は、下記にあります。すべてを確認するためには、Download ZIPからZIPをダウンロードしてください。
最初に、テーブルと機能を説明し、続いて、環境構築や実行方法を説明します。
最後に、ファイル構成と、抜粋したコードや補足の説明をします。
参考
- FastAPI版のサンプルコードの記事もあります。
- 参考にしたチュートリアル
テーブルとカラム
著者テーブルと書籍テーブルを操作します。データベースは、SQLiteを使います。
テーブル | カラム |
---|---|
著者(Author ) |
ID(id )、名前(name )、書籍(books ) |
書籍(Book ) |
ID(id )、名前(name )、著者ID(author_id )、著者(author ) |
-
Book.author_id
は、Author.id
の外部キー -
Author.books
とBook.author
は、リレーション用
機能
2つの表を操作する10の機能があります。
method | パスとパラメーター | 関数 | 説明 |
---|---|---|---|
POST | /authors?name=... |
add_author() |
著者の追加 |
GET | /authors |
get_authors() |
全著者の取得 |
GET | /authors?author_id=... |
get_author() |
指定著者の取得 |
PUT | /authors?author_id=... |
update_author() |
指定著者の更新 |
DELETE | /authors?author_id=... |
delete_author() |
指定著者の削除 |
POST | /books?title=... |
add_book() |
書籍の追加 |
GET | /books |
get_books() |
全書籍の取得 |
GET | /books?book_id=... |
get_book() |
指定書籍の取得 |
PUT | /books?book_id=... |
update_book() |
指定書籍の更新 |
DELETE | /books?book_id=... |
delete_book() |
指定書籍の削除 |
- 著者と書籍が親子構造になっている
- 書籍を追加するには、親となる著者が必要
- 指定著者を削除すると、子供である書籍も削除される
環境構築
Python 3.12
で動作します。uvが必要です。
以下のようにしてLitestarの仮想環境を作成します。
uv venv
Litestarの起動
以下のようにしてLitestarを起動します。
uv run litestar run --reload
対話的APIドキュメント
下記から対話的APIドキュメント(Swagger UI)が使えます。
REST APIのファイル構成
シンプルなので、ソースファイルを1ファイル(app.py
)にまとめています。
app.py
の解説
ポイントごとに簡単に紹介します。なお、異常系の処理では処理不足の部分が残っています。
plugins
SQLAlchemyInitPlugin
を使うと、DBの初期化を設定できます。
また、SQLAlchemySerializationPlugin
を使うと、DBのレコードからPydanticのオブジェクトにシリアライズ可能になります。このため、このサンプルではPydanticのクラス定義は不要になっています。
sqlalchemy_config = SQLAlchemyAsyncConfig(
connection_string="sqlite+aiosqlite:///db.sqlite3",
session_config=AsyncSessionConfig(expire_on_commit=False),
)
app = Litestar(...,
plugins=[SQLAlchemyInitPlugin(config=sqlalchemy_config), SQLAlchemySerializationPlugin()],
)
Pydanticのクラスを定義する場合は、下記が参考になります。
on_startup
on_startup
で、起動時の処理を指定できます。ここでは、テーブルを作成しています。
async def on_startup() -> None:
async with sqlalchemy_config.get_engine().begin() as conn:
await conn.run_sync(UUIDBase.metadata.create_all)
app = Litestar(on_startup=[on_startup], ...)
DBのクラス定義
UUIDBaseから派生すると、id
を主キーとして自動的に追加します。また、サンプルでは使用していませんが、UUIDAuditBaseから派生すると、id
、created_at
、updated_at
を追加します。
なお、テーブル名はクラス名をスネークケースにしたものになります。
class Author(UUIDBase):
name: Mapped[str]
books: Mapped[list["Book"]] = relationship(...)
パスオペレーション関数
SQLAlchemyInitPluginを使っているので、パスオペレーション関数の引数に、セッションとしてdb_session
が使えます。
また、SQLAlchemySerializationPluginを使っているので、クエリ結果から自動的にPydanticのオブジェクトに変換されます。
@get(path="/author", tags=["/authors"])
async def get_author(author_id: str, db_session: AsyncSession) -> Author | None:
return await db_session.get(Author, author_id)
Qiitaの記事
以上