LoginSignup
0
0

オニオンアーキテクチャでFastAPIで勉強してみた

Posted at

背景

オニオンアーキテクチャを理解したかったので、FastAPIをオニオンアーキテクチャで作ることにした!

とは言ったものの、オニオンアーキテクチャを調べると難しかったので、自分が理解できるレベルに噛み砕いてみた

前提知識

オニオンアーキテクチャ
よく見つやつ↓

Group 1.png

勉強スタート

ディレクトリ構成

以下のディレクトリ構成を作る

interface/      # アプリケーションが外部システムと通信するためのAPI

application/    # DB操作、トランザクション管理、外部サービスなどを組み合わせる

domain/         # モデル、モデルを作ったり、計算するサービス

infrastructure/ # 外部サービスとの連携, DB との連携

オニオンアーキテクチャの絵を書き直す

Group 2.png

基本的なデータの流れ

赤の矢印に沿ってプログラムが進んでいく。

逆向きに進んではNG!
NG例: DomainServiceからApplicationServiceを呼び出してはいけない

Group 4.png

DBが操作できない?

この絵の通りプログラムを書いていくと、壁にぶち当たった

ApplicationServiceでDBを更新したりするのだが、DBを更新するプログラムはinfrastructure/にある

矢印の向き的に、ApplicationServiceからinfrastructure/を呼び出せない。
これを解消するために、domain/にInterfaceを作る。
DomainInterfaceはただの箱。実体は、infrastructure/にある。
interface/api を実行する時に、箱の中身も渡してあげるイメージ

コードだとこんな感じ

# domain/interface/repositories/message_repository.py
class IMessageRepository(ABC):
    @abstractmethod
    def find_by_id(self, message_id: int) -> Message:
        pass

    @abstractmethod
    def save(self, message: Message) -> Message:
        pass
# infrastructure/repositories/message_repository.py
class MessageRepository(IMessageRepository):
    def __init__(self, session: SQLAlchemySession) -> None:
        self.session = session

    def find_by_id(self, message_id: int) -> Message:
        try:
            p_message = (
                self.session.query(MessagePersistence).filter_by(id=message_id).one()
            )
            return self._create_message_from_persistence(p_message)
        except Exception:
            raise

    def save(self, message: Message) -> Message:
        p_message = MessagePersistence.create(message)
        try:
            self.session.add(p_message)
            if self.session.in_transaction():
                self.session.flush()
            else:
                self.session.commit()
            return self._create_message_from_persistence(p_message)
        except Exception:
            raise

イメージ
Group 5.png

最終的に出来上がったもの

interface/
|- api/             # API

application/
|- services/        # DB操作、トランザクション管理、外部サービスなどを組み合わせる

domain/
|- services/        # DomainModel作成、計算処理
|- models/          # プログラム全体で利用するモデル
|- interfaces/
   |- repositories/ # infrastructure/respositoriesを呼び出すための箱
   |- externals/    # infrastructure/externalsを呼び出すための箱

infrastructure/
|- repotitories/    # DBの処理
|- externals/       # 外部サービスの呼び出し

感想

オニオンアーキテクチャの基本的な流れが理解できた。
まだ、書いてないがテストがやりやすそう。
ただ、コード書く量が多いなーとは正直思った。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0