🦝

「なんちゃってクリーンアーキテクチャ」を基にしたLaravelでの開発方針

2024/03/24に公開

APIを開発する際のLaravelの構成は、「なんちゃってクリーンアーキテクチャ」を基にしているのですが、いくつかのプロジェクトを経験する中で、アレンジしたり、ルールがあったほうが良いことがあったので、開発方針としてまとめています。

「なんちゃってクリーンアーキテクチャ」について

mpyw 氏が 5年間 Laravel を使って辿り着いた,全然頑張らない「なんちゃってクリーンアーキテクチャ」という落としどころ の記事で書かれているLaravelの構成のことです。

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

詳しくは上記の記事を参照ください。

ファイル構成

ファイル構成は以下のようにしています。

app/
    Console/
    Exceptions/
    Http/
        Controllers/ : コントローラー用のディレクトリ
        Middleware/
        Requests/ : リクエスト用のディレクトリ
        Resources/ : APIリソース用のディレクトリ
        UseCases/ : コントローラーから利用するユースケース用のディレクトリ
    Models/
    Providers/
    UseCases/ : コントローラー以外から利用するユースケース用のディレクトリ
bootstrap/
config/
database/
lang/
public/
resources/
routes/
storage/
tests/

アレンジした内容

1つのAPIに対して、リクエスト、ユースケース、リソースは1つずつ作成する

APIを1つ追加するだけで一気にファイルが3つも必要になるのか(テストのファイルなども含めればもっと)、と思うかもしれませんが、他のAPIへの影響を気にせずに修正することがいつでもできる、という状態にしておいた方がメンテナンスがしやすいです。
ただ、内容がまったく同じクラスが複数ある、ということになってしまう場合もあるので、その場合は以下のような方法で共通化します。

リクエスト

  • 共通する処理を別のクラスにまとめる
  • 内容がまったく同じクラスを空継承する ※

ユースケース

  • 後述する「海中レベルのユースケース」を作成する

リソース

  • 共通する処理を別のクラスにまとめる
  • 内容がまったく同じクラスを空継承する ※

※以下のサンプルのように、あるクラスを継承するが一切の変更を加えないことを便宜的に「空(から)継承」と表現しています。

class A
{
    public $a;

    public function hello()
    {
        return 'hi!';
    }
}

class B extends A
{
}

ユースケースは「海面レベル」と「海中レベル」に分ける

コントローラーから直接利用されるユースケースと、共通処理などのユースケースから利用されるユースケースの場所は分けておいた方が良いです。
コントローラーから直接利用されるユースケースには、APIやデータベースなどの都合に合わせるためのロジックが必要な場合があり、そのような都合を吸収するためのユースケースと、ドメインロジックのユースケースは明確に分離した方が分かりやすいです。

コントローラーから直接利用されるユースケースは「海面レベル」のユースケース、そのユースケースから利用されるユースケースは「海中レベル」のユースケースとし、海面レベルのユースケースは app/Http/UseCases ディレクトリに、海中レベルのユースケースは app/UseCases ディレクトリに格納するようにしています。

ユースケースの「海面レベル」「海中レベル」については、以下の記事を参考にしました。

https://yoskhdia.hatenablog.com/entry/2016/10/18/152624

GitHubで編集を提案

Discussion