Laravel なんちゃってクリーンアーキテクチャの学習

Posted date at 2024-04-08

php

目的

個人開発しているLaravel製APIが膨らんできたのでメンテナンスしやすそうなアーキテクチャにリファクタリングする。見た感じかなり指示されていそうだし、考えを自分にとりこんでいきたい。

https://zenn.dev/mpyw/articles/ce7d09eb6d8117

Laravelの機能を利用して処理を分割する。

  • ポリシーを使うと認可判定ロジックを外に出せる
    • 権限の判定処理はドメインロジックのノイズになりやすい
  • フォーマットバリデーションをFormRequestに切り出す
    • バリデータの検証部分
    • 認可処理も行える。(記事も言っているけど、先に権限判定したほうがいいからここでやってしまうほうに賛成)
  • Resource を利用してレスポンスを成型する
    • 柔軟に成型できるし、API仕様をわかりやすくすることにもつながる
    • 属性をすべて列挙するほうがいい。

モデルにドメインロジックを集約

コントローラーから最も移植されやすいModel

ActiveRecordパターンの宿命で、メソッド名が衝突することがあり、命名に苦しむこととなる。

また、実装が肥大化する。(今までは自分はService層を切ってロジックを書いていた。この場合はModelはORM用にしてる)

サービスクラスに集めた場合

	- サービスクラスが肥大化する(実体験あり)→ 1アクション1クラスの考えがベスト
	- ドメインサービスとインフラサービスの2種類が存在する
		- インフラサービスはAWSのS3への保存をラップしたいとか

クリーンアーキテクチャをもし Laravel に厳格に適用したら?

  • オーバースペックすぎる。

  • Eloquent ModelをRepositoryが返すとUseCaseで→save() を実行できる。(これはクリーンアーキテクチャ的にはNG)

     Entityに処理を詰め替えればこの問題自体は解決できる

  • Eloquent Builderの機能が使えなくて、Laravel採用理由が薄れる。

UseCase だけを取り入れた, Laravel 向けに妥協したクリーンアーキテクチャ

Eloquentを使うために妥協したクリーンアーキテクチャの形。

自分がよくやっている、「サービスクラス」の肥大化よりはマシ。

ドメインサービスを単一責任にしてユースケースとして扱う。

インフラサービスを「app/services」に置き、ドメインサービスを「app/UseCases」に置く。

app/ ├─┬ Console/ │ ├── Commands/ │ └── Kernel.php ├─┬ Exceptions/ │ └── Handler.php ├─┬ Http/ │ ├─┬ Requests/ │ │ ├─┬ User/ │ │ │ ├── StoreRequest.php │ │ │ └── UpdateRequest.php │ │ └─┬ Post/ │ │ ├── IndexRequest.php │ │ ├── StoreRequest.php │ │ └── UpdateRequest.php │ ├─┬ Resources/ │ │ ├── UserResource.php │ │ ├── CommunityResource.php │ │ └── PostResource.php │ ├─┬ Controllers/ │ │ ├── UserController.php │ │ ├── CommunityController.php │ │ ├── PostController.php │ │ └── Controller.php │ ├── Kernel.php │ └── Middleware/ ├─┬ Models │ ├── User.php │ ├── Community.php │ └── Post.php ├── Providers/ └─┬ UseCases/ ├─┬ User/ │ ├── StoreAction.php │ └── UpdateAction.php ├─┬ Community/ │ ├── StoreAction.php │ └── UpdateAction.php └─┬ Post/ ├── IndexAction.php ├── StoreAction.php ├── UpdateAction.php ├── DestroyAction.php └─┬ Exceptions/ └── PostLimitExceededException.php

テストどうするの?

ユニットテストをあきらめて機能テストをかく。

個人開発でリリースにこぎつけていないため、ユニットテストまで厳密にするモチベがないけど最低限のテストは書きたい状況なので、これでいいと思っている。

クエリスナップショットテストが有効

書きやすいし安全性を維持する効果が高い。

UseCase以外のテストをどう書くか

FormRequestをテストするべき。


ユニットテスト風に記載できる
←ホームに戻る