🐘
[PHP][Laravel]Repositoryパターン適用例
published_at: 2019-04-23 07:59
これはなに?
- Laravel での Repository パターンの実装例について記述したものです
- Repository パターンそのものについては説明してません
情報
- 参照した
- 自分で試したコード
検証環境
- macOS Mojave 10.14.4
- Docker version 18.09.2, build 6247962
- docker-compose version 1.23.2, build 1110ad01
- PHP 7.3.3 (cli) (built: Mar 27 2019 01:21:44) ( NTS )
- Laravel Framework 5.8.7
適用方法
(事前準備)検証用DB整備
- Modified Files
- .env.example
- DBコンテナ(db-host)に接続するように調整
-
ln -snf .env.example .env
でシンボリックリンクにして .env を整備
- .env.example
- Added Files
- server/database/migrations/2019_04_19_032013_create_fruits_table.php
- マイグレーションコード
- server/database/seeds/FruitsTableSeeder.php
- データシーダー
- server/app/Models/Fruit.php
- モデルクラス
- server/database/migrations/2019_04_19_032013_create_fruits_table.php
- データ適用
❯ docker exec -it php bash root@3e0a1cbf0ad1:/var/www# php artisan migrate Migrating: 2019_04_19_032013_create_fruits_table Migrated: 2019_04_19_032013_create_fruits_table root@3e0a1cbf0ad1:/var/www# php artisan db:seed --class=FruitsTableSeeder Database seeding completed successfully. root@3e0a1cbf0ad1:/var/www# exit exit
実装調整
app/Providers
- ServiceProvider追加
- server/app/Providers/RepositoryServiceProvider.php
- register メソッドに以下のような定義を追加
// Fruit $this->app->bind( FruitRepositoryInterface::class, //<- インターフェース FruitDbRepository::class //<- 実体クラス:切り替えるならここを変える );
- register メソッドに以下のような定義を追加
- server/app/Providers/RepositoryServiceProvider.php
- ServiceProviderのファイルを追加した場合、定義の追加が必要
- server/config/app.php
-
providers
に追加'providers' => [ ・・・ /* * Application Service Providers... */ ・・・ App\Providers\RepositoryServiceProvider::class, //<- コレ
-
- server/config/app.php
app/Repositories/Fruit
- インターフェース
- server/app/Repositories/Fruit/FruitRepositoryInterface.php
- 必要なメソッドの定義のみ列挙
- server/app/Repositories/Fruit/FruitRepositoryInterface.php
- 実体クラス
- server/app/Repositories/Fruit/FruitDbRepository.php
- implements でインターフェースの実体クラスであることを宣言
- インターフェースで定義したメソッドを全て実装
- (わざわざ Fruit クラス(Model) を extends したが、 Fruit クラスを実体クラスにするのもありかもしれない)
- server/app/Repositories/Fruit/FruitDbRepository.php
ルーティング・コントローラー周り
- ルーティング
- server/routes/api.php
- 呼び出すコントローラーへのエントリを追加
- server/routes/api.php
- コントローラー
- server/app/Http/Controllers/FruitController.php
- index メソッドに、リポジトリパターンを使用せずにモデルクラスでDB内のデータを取得するメソッドを実装
- see
http://localhost/api/fruit/all
- see
- show メソッドに、リポジトリパターンを使用してDBからデータを取得するメソッドを実装
- see
http://localhost/api/fruit/[0|1|2|3]
- see
- index メソッドに、リポジトリパターンを使用せずにモデルクラスでDB内のデータを取得するメソッドを実装
- server/app/Http/Controllers/FruitController.php
今後の展開など
- 例えば server/app/Repositories/Fruit/ に FruitCsvRepository.php のようなクラスを作成して、
以下のように変更することで実体クラスを切り替えられるのではないかと思う。- データ処理メソッドを実装し、
-
implements FruitRepositoryInterface
を FruitDbRepository から移動 - FruitController のコンストラクタで new するのを FruitCsvRepository に変更
-
- server/app/Providers/RepositoryServiceProvider.php で 実体クラスを FruitCsvRepository::class に切り替え
- データ処理メソッドを実装し、
- これを利用した安全なデータ運用ができそう、かと。
- DB なくても CSV で、とか。(読み込み処理とか作成の必要ありますが)
- 他にも、最終的には SSO にするシステムなんだけど、当面は手元の User テーブルで動作を試す場合などにも。
留意事項
- autoloader がおかしい感じになったらコンテナに入って
composer dump-autoload
するなどが時には必要。 - provider コードの生成は
php artisan make:provider RepositoryServiceProvider
で行うのが良さそう。
Discussion