以下のように整理しておきます。question_datamodeltoModelとtransferToDataModelではデータの詰め替えを行っています。FastAPIとしてはDataModelでないとフレームワークの仕様に沿わないので都合が悪いです。一方で、開発者としてはDDDで解釈したい気持ちがあります。その変換をRepositoryのレイヤーで行い必要に応じてデータの詰め替えをします。イメージとしては以下のような感じです。DDDにおけるRepositoryの役割DDDにおけるリポジトリの役割はデータの永続化と再構築です。再構築はselectになります。DDDにおけるRepositoryのメリット今まで自分の開発の経験として、DBMS(MySQLなど)を利用したテストは書いていました。DBMSを利用するテストにはデメリットがあります。それはDBMSを利用して直接、データを再構築するようなテストは、実行するサーバーや実行するタイミングといった環境の違いによって結果がばらつくことです。環境による不都合が生じてしまいます。DDDもしくはレイヤーに分けることで、それぞれのレイヤーで開発するフレームワークに依存しないテストを作ることができます。これがDDDのメリットです。以下では、実際にコードを示していきます。今回、FastAPIではORMとしてSQLalchemyを利用しています。以下のコードではQuestionを保存(永続化)する処理を実装しています。テストを書くときにこのリポジトリを利用すると、DBに対して実際に登録することになり前述したような環境による不都合が起きることになります。session.commit()InMemoryなリポジトリの実装そこで直接DBにアクセスをしないメモリ上にデータを保存するリポジトリを実装します。リポジトリが交換可能であることを担保するここでInMemoryのリポジトリとDBにアクセスするリポジトリが同じ処理をするもの、交換可能であることを担保するために、以下のような抽象クラスを用意しておきます。(いわゆる、依存性逆転の法則です。このようにInMemoryのリポジトリとDBにアクセスするリポジトリをそれぞれ用意することで、テストを実行する際に環境による不都合が起きることはなくなります。開発者の精神衛生的にも気軽にテストを実行できるのはメリットでしょう。実行速度としてもInMemoryのリポジトリのほうが速いのもメリットです。FastAPIから自動生成されるswaggerとDDDFastAPIにはswaggerを自動生成してくれる機能があります。objectを実装してもそれをよしなに認識してくれることはありません。swaggerをそれなりの形にしたい場合は、FastAPIの仕様に則った書き方をする必要があります。具体的にはこんな感じ。question_responsesswaggerを確認するリクエスト、レスポンスをそれぞれクラスとして定義し、メソッドのアノテーション、引数につけるとswaggerはいい感じに出力されます。CreateQuestion):出力されるswaggerはこんな感じ。swagger上からAPIをコールもできます。pycacheのディレクトリが散在する**__pycache__**というディレクトリが散在することになりました。.gitignoreにその都度書いて、バージョニングの対象外にするのですけど、これにはなにかいい方法がありそうだと思っています。知っている方いたら教えてください。まとめDDDの設計思想はFastAPIに限らず、いろんなフレームワークに適用できる部分がとても有用に感じています。個人的には各レイヤーでテストがかけることにとても助かっています。そんな感じで今回の記事はここまでです。ツイートカラビナテクノロジーカラビナテクノロジーのテックブログですバッジを贈って著者を応援しようバッジを受け取った著者にはZennから現金やAmazonギフト券が還元されます。pycacheのディレクトリが散在するまとめZennエンジニアのための情報共有コミュニティAboutZennについて運営会社お知らせ・リリースGuides使い方Publicationよくある質問LinksTwitterGitHubメディアキットLegal利用規約プライバシーポリシ。