LaravelでWEBサービスを立ち上げる為のテンプレートを用意する
概要
Laravelを用いてWebサービスを立ち上げる際の基本的な構成を用意する。 最近リポジトリパターンが流行っているようなので、その構成をテンプレート化しておいてすぐに使えるように用意しておく。 この構成にどんな意味があるかは手を動かしながら理解していってほしい。
1.プロジェクト作成 Laravel-Installerでプロジェクトを作成。
$ laravel new SampleProject
2.ディレクトリを追加する DBへのアクセスを担うRepositoriesと、ビジネスロジックを纏めるServicesを置くディレクトリを作成する。基本的にどこに配置してもいいが、よく見るのはappの配下に置くパターン。
├── app │ ├── Console │ ├── Exceptions │ ├── Http │ ├── Services // 追加 │ ├── Repositories // 追加 │ └── ... ├── bootstrap ├── config ├── ... ...
3.マイグレーションファイルの作成
今回は既存のUserテーブルに加えCompanyテーブルを用意する。下記のコマンドでモデルとマイグレーションファイルがセットで出来上がる。その後はphp artisan migrate
でテーブルの作成を行う。
php artisan make:model CompaniesTable --migration
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateCompaniesTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('companies', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('name', 100)->default(""); $table->string('address', 200)->default(""); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('companies'); } }
4.コントローラーの作成 最近はRestApiでの開発がメインになりつつあるので下記でコントローラーを作成する。
php artisan make:controller CompanyController --resource
5.各ファイルの手配 2.で用意したSercices、Repositoriesディレクトリに下記のファイルを用意する。
・CompanyService.php // Servicesディレクトリ内に配置 ・CompanyRepository.php // Repositoriesディレクトリ内に配置 ・CompanyRepositoryInterface.php // Repositoriesディレクトリ内に配置
6.ロジックを組み立てる 下地が整ったので、あとはロジックを組み立てていく。まずはコントローラーにメソッドを記述する。ここでは同時にCompanyServiceを注入している。Companyが不動産関係なら所有物件の有無を確認し...といったビジネスロジックはCompanySrerviceに記述することになるので、コントローラーではCompanyServiceで「何をするか」が分かるように記述する。実際のロジックはCompanyServiceの中で記述すること。
<?php namespace App\Http\Controllers; use App\Http\Requests\CompaniesRequest; use App\Services\CompanyService; class CompanyController extends Controller { /** @var companyService */ protected $companyService; /** * @param CompanyService $companyService * */ public function __construct(CompanyService $companyService) { $this->companyService = $companyService; } /** * Store a newly created resource in storage. * * @param CompaniesRequest $request * @return array */ public function store(CompaniesRequest $request) { $company = $this->companyService->createCompany($request->only(["name", "address"])); return response()->json($company, 200); } }
次にCompanyService.phpを作成していく。上で述べたように、ここにコントローラーで使うであろうメソッドを定義していく。上の流れに沿って不動産関係の会社でゴニョゴニョしたいならisEstateCompany()
やisOwner()
など必要なメソッドをコントローラーを意識して用意する。
<?php namespace App\Services; use App\Repositories\CompanyRepositoryInterface; class CompanyService { protected $companyRepository; public function __construct(CompanyRepositoryInterface $companyRepository) { $this->companyRepository = $companyRepository; } public function createCompany($request) { return $this->companyRepository->createCompany($request); } }
次にInterfaceを用意する。Interfaceはメソッドを保証する目的で作成する。例えばcreateCompanyはDBに会社を新規登録するメソッドである為、このInterfaceを実装するのはCompanyRepositoryになるが、CompanyRepositoryには必ずcreateCompany()
が定義されていなければならない。なぜこのような面倒なことをするか、と言うのはこの後説明する。
<?php namespace App\Repositories; interface CompanyRepositoryInterface { public function createCompany($request); }
ここでAppServiceProvider.phpにこのInterfaceとRepositoryの紐付けを行う。Interfaceを使用する意味はここにある。ここではCompanyRepositoryInterfaceとCompanyRepositoryを紐付けているが、このRepositoryは差し替えが可能である。例えば.envがAPP_ENV=local
ならばCompanyRepositoryでAPP_ENV=production
ならばApiCompanyRepositoryを使用するといったDBの切り替えをここで定義することができる。この他にも、例えば会社登録などほぼ固定化され変わることのないメソッドは必ず用意してくれと言う意味でもInterfaceの存在意味は出てくる。
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { $this->app->bind(\App\Repositories\CompanyRepositoryInterface::class, \App\Repositories\CompanyRepository::class); } }
最後にCompanyRepositoryのコーディングを行う。ここではModelのCompany.phpを注入する。Modelにはリレーションやfillable
など基本的な共通事項を定義しておけばRepositoryを複数用意する場合にも便利だろう。
<?php namespace App\Repositories; use App\Company; class CompanyRepository implements CompanyRepositoryInterface { protected $company; public function __construct(Company $company) { $this->company = $company; } public function createCompany($request) { return $this->company->create($request); } }
7.まとめ DBへのアクセスロジックはRepositoryへ、ビジネスロジックはServiceへ、コントローラーへは派生先で何が行われるかが見ただけで分かるようにするのが理想である。
Homesteadのphp.iniを編集する
Homesteadのphp.iniを編集する。 ディストリビューションはUbuntuなので下記手順で更新を行う。
vagrant@homestead:~$ cat /etc/issue Ubuntu 16.04.3 LTS \n \l
1. php.iniの場所を確認する
// 1. phpのバージョンを確認 vagrant@homestead:~$ php -v PHP 7.2.2-1+ubuntu16.04.1+deb.sury.org+1 (cli) (built: Feb 1 2018 16:01:26) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.2.2-1+ubuntu16.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies with blackfire v1.18.2~linux-x64-non_zts72, https://blackfire.io, by SensioLabs // 2. etc配下にphpフォルダがあるので使用しているバージョンのフォルダに入る。 vagrant@homestead:~$ cd /etc/php vagrant@homestead:/etc/php$ ls -l total 16 drwxr-xr-x 5 root root 4096 Feb 5 2018 5.6 drwxr-xr-x 5 root root 4096 Feb 5 2018 7.0 drwxr-xr-x 5 root root 4096 Feb 5 2018 7.1 drwxr-xr-x 5 root root 4096 Feb 5 2018 7.2 // 3. このバージョンフォルダの中のfpmというフォルダ内にphp.iniがある。 vagrant@homestead:~$ cd /etc/php/7.2/fpm
2. php.iniのRW権限付与
$ sudo chmod -R ugo+rw php.ini
3. php.ini編集
$ sudo vi php.ini
Laradock環境構築
Laradockとは
Laravelのアプリを開発する上で必要なComposer、MySQL、Nginxなど諸々のDockerコンテナを作成する為のイメージが入ったパッケージ。これらのコンテナを組み合わせアプリ開発をしていく。VagrantでいうHomesteadのような存在。
Dockerイメージとは
コンテナを作成するためのファイルシステム。イメージは公式な「リポジトリ」で配布されているもの(ベースイメージ)を取得してきてもよいし、自作することもできる。例えばRubyとMySQLのパッケージを追加してひとつのイメージにしておけば、これを様々な環境で同一に使いまわすことができる。何と何を組み合わせるかはDockerfileに定義しておく。 今回はLaradockが提供しているイメージを使用することになるが、LaradockはLaravelやComposer等プログラム系を纏めたworkspace、WebサーバーであるNginx、DBのMySQLという単位でイメージを切り分けてある。(他にもRedis、phpMyAdminといった単位でたくさん用意してある) とりあえずのアプリを作成するのならworkspace、nginx、mariadbのイメージからコンテナを作成すればいい。
環境構築
準備
今回のフォルダ構成は下記の通り。
laradockと同階層にプロジェクトフォルダを置く。
projectフォルダ配下にはapp,bootstrap,config...とLaravelのフォルダが続く。
ちなみに既にプロジェクトフォルダがある場合、後ほど記載するlaradockの.envのマウントフォルダのパス設定を変えれば良い。
使うDBをプロジェクトによって切り替えたい場合は、laravelの.envを変えること。
Documents/ ├ laradock/ ├ project/
手順1.LaradockをCloneする
git clone https://github.com/LaraDock/laradock.git
手順2.laradock用の.envを用意する
cd laradock cp env-example .env
これはLaravelの.envではなくLaradockの.envである。 この.envに、コンテナとマウントするプロジェクトフォルダ等を定義していく。
「準備」記載のフォルダ構成を前提にlaradockの.envにマウントフォルダを下記のように定義する。
APP_CODE_PATH_HOST=../project
手順3.コンテナを作成する
docker-compose up -d nginx mariadb phpmyadmin redis workspace
最初はなかなか時間が掛かる。次からは早い。
手順4.コンテナの起動を確認する
docker-compose ps
stateがUpになっていればコンテナが起動している。
※ここでmariadbが動いていない問題が発生!!とりあえず下記の対応で何とかなった。
volumes: - - ${DATA_PATH_HOST}/mariadb:/var/lib/mysql + #- ${DATA_PATH_HOST}/mariadb:/var/lib/mysql
手順5.Laravelプロジェクトの作成
workspaceというコンテナに入りcomposerでプロジェクトを作成する。 まずは下記のコマンドでworkspaceコンテナに入る。
docker exec -it laradock_workspace_1 /bin/bash
ここでls -l
すると、どのフォルダ階層かが分かる。「準備」記載の階層にプロジェクトフォルダを作るとして、Composerでプロジェクトを作成していく。
composer create-project laravel/laravel docker_app
完了
workspaceでphp artisan serve
で稼働を確認できる。
その他
Laravelの.envのDB初期値設定は下記である。
DB_CONNECTION=mysql DB_HOST=mariadb DB_PORT=3306 DB_DATABASE=default DB_USERNAME=default DB_PASSWORD=secret