「なんちゃってクリーンアーキテクチャ」を基にしたLaravelでの開発方針
APIを開発する際のLaravelの構成は、「なんちゃってクリーンアーキテクチャ」を基にしているのですが、いくつかのプロジェクトを経験する中で、アレンジしたり、ルールがあったほうが良いことがあったので、開発方針としてまとめています。
「なんちゃってクリーンアーキテクチャ」について
mpyw 氏が 5年間 Laravel を使って辿り着いた,全然頑張らない「なんちゃってクリーンアーキテクチャ」という落としどころ の記事で書かれているLaravelの構成のことです。
詳しくは上記の記事を参照ください。
ファイル構成
ファイル構成は以下のようにしています。
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
ディレクトリに格納するようにしています。
ユースケースの「海面レベル」「海中レベル」については、以下の記事を参考にしました。
Discussion