古のエンジニアがlaravelを初めて触って習熟していく流れで、とても参考になった記事まとめ

## 経緯
普段はフロントエンド、vueやnuxtの開発を中心にやっています。今回はバックエンドも含めて開発する案件を受注したことをきっかけに、最近流行ってるlaravelでバックエンドを作ってみるか、ということになりました。

もともと、LAMP環境の構築やphp,mysqlは経験がある古のエンジニアです。
以前は素のphp+mysqlでフレームワークを使わずゴリゴリ書いていました。

開発環境はlinux(CentOS)をベアメタルサーバーにインストールして、phpやmysqlをソースからインストールしたりして使う、そういう時代のエンジニアです。HTTPサーバーといえばapacheでしょ？という時代から、最近のAWSは便利だよね〜という時代を生きてきた人です。

ちなみにデータセンターにオンプレミス環境を構築して月間数億PVのアクセスがあるソシャゲの開発運用とかを一人でやったりしていました。AWSに移行してからはRDSの負荷分散のためmemcachedサーバーにキャッシュレイヤーを作ったり、懐かしい。

話はそれてしまいましたが、最近はフロントエンド中心の開発案件をやっています。
バックエンドとのやり取りはAPIでやることが主流の時代になってきました。

久しぶりにバックエンド作るので、最新のモダンで人気なフレームワークをいっちょやってやるか！と思い人気のlaravelに目をつけたわけです。

## laravelを選んだ理由

1. 日本語で書かれたドキュメントやサンプルが多い
2. AWSとの連携が組み込み済み
3. API用のレイヤーが標準装備
4. Model経由でのDBとの密な連携

この辺です。テーブル作成はphpmyadminで、PHPの中にSQLを直書きしていた私からすると、アプリケーション内からModelでDBと密接に結合しているのは新鮮です。

フロントエンドとはAPIで連携するので、その辺の機能も標準装備していることに魅力を感じました。

## 開発環境構築

https://qiita.com/ucan-lab/items/5fc1281cd8076c8ac9f4

Laravel環境構築はこちらの神リポジトリをcloneしてdockerで一発です。すごい便利な時代になったものですなぁ、昔はLinuxのインスト(ry

## laravelのtableを作ってみて、表示させてみる

えっ！DBのテーブルってphpmyadminでチマチマ作るんじゃないんですか？

なるほど、作成、変更履歴も残せるマイグレーションと言うのがあるのか…

https://noumenon-th.net/programming/2020/01/15/laravel-mysql/

## larvel passportでAPI認証のバックエンド側基本を作る→やめた

シンプルなjwtに切り替えました。

https://www.whizz-tech.co.jp/1442/

### composer dumpautoloadってなんだ？

おかしくなったときはこれ。でもあまり使わない。

https://qiita.com/WebSysRider/items/e41f211f8c913e008d03

## laravel上でvueベースの認証画面を作る

基本のapiのやりとり。

https://www.whizz-tech.co.jp/1453/

### nodeが無いと言われたのでこちらでDockerを再構築

https://zukucode.com/2019/06/docker-laravel-nodejs.html

http://127.0.0.1/register
にアクセスしてみる

npm run devが抜けていたため、以下のファイルが見つからんかった

/css/app.css  178 KiB  /js/app  [emitted]  /js/app
  /js/app.js  1.4 MiB  /js/app  [emitted]  /js/app

再度アクセスするとうまくいった

### Personal access client not found. Please create one. エラーがでる
php artisan passport:client --personal

上記コマンドならうまくいく、

その後webで再度やるとうまく行った。なんでや?

これが回答かな？
https://stackoverflow.com/questions/56249565/why-we-have-to-create-personal-access-client-in-passport-again-and-again

makefileのinitに以下のコマンドを追加した→削除
```
docker-compose exec app php artisan passport:install
```

## laravelのアクセスがやったら重いんですけど

Docker for Mac限定の問題。
色々試しましたけど、最終的には直接php artisan serveすることで解決。

dockerのvolumeのマウントが原因。 :delegatedをつけたら少し軽くなった。

https://wonwon-eater.com/mac-docker-performance/

## /api/userにアクセスしてもなにも起こらない

忘れがち

> なお、JSONが返されるのはLaravel5.3のデフォルトではヘッダーにX-Requested-With: XMLHttpRequestがある、またはAcceptヘッダーでjsonが指定されている場合です。(fetchにネイティブ対応しているブラウザではそれを使用した場合明示的にAcceptを指定してやらないと前者の対象にはならずにリダイレクトが発生し200になります。宇宙。)
https://blog.hinaloe.net/2016/09/15/try-passport-laravel-5-3/

Acceptヘッダとauth Bearerヘッダを追加して再確認、うまくいった。

## よく考えたら、backendフォルダ内で直接laravel動かしたらいいんじゃね？

→動いた。ローカルなので応答も早い。
DBの接続情報を変更する必要がある。Dockerコンテナは環境変数を変更しているため。

```
DB_DATABASE=laravel_local
DB_USERNAME=phper
DB_PASSWORD=secret
```

### .envの更新を反映させるにはコマンドが必要

```
php artisan cache:clear
php artisan config:cache
```

## passportやめたい

composer.jsonを編集して composer update

https://ja.coder.work/so/laravel/545565

## 認証APIをjwtで作り直し

参考
https://re-engines.com/2019/06/03/laravelで認証apiを作る/
うごかないなんでや
https://github.com/tymondesigns/jwt-auth/issues/1484

>replace
'expires_in' => auth()->factory()->getTTL() * 60
by
'expires_in' => auth('api')->factory()->getTTL() * 60

うごいた。ここでtokenの有効期限も設定できるっぽい

## 認証APIにregisterを移植した
バリデーションも合わせて実装した

## userのcrudをAPIで実装する
参考
https://qiita.com/sutara79/items/cd4371b246b44a2cf87f

### putのrequestが空っぽなんなんでや？？
postmanの設定だった

https://qiita.com/wjtnk/items/eb2ddcc0642dc3197671

## PUT時にuserが見つからない場合に出るModelNotFoundExceptionエラーをカスタマイズする

abortの第一引数にresponceを渡さないとstach traceが出るみたいだぞ？

https://laraveldaily.com/laravel-api-404-response-return-json-instead-of-webpage-error/

その他、細かく設定する場合
https://qiita.com/sakuraya/items/af38c4cf84459a8b5967

基本形

```:Handler.php
    public function render($request, Throwable $exception)
    {
        if ($exception instanceof ModelNotFoundException) 
        {
          abort(response()->json(['message' => 'not found'], 404));
        }
        return parent::render($request, $exception);
    }
```

## コードフォーマッタとリンターがないので入れる

https://www.ritolab.com/entry/188#aj_3

## 開発用のメールサーバー
ブラックホールメールサーバーのDockerコンテナを開発用に立てる
http://127.0.0.1:1080 で送信したメールが全部見れる。なんて便利な世の中や・・

https://qiita.com/kanemu/items/1f2da063c7e5b5477502

## seederでダミーデータを適当に作る。マスタデータも作れる。

https://qiita.com/shosho/items/b69db263a494edfe3b21

## Route::resources で全部使わないよ！って場合

https://qiita.com/sympe/items/9297f41d5f7a9d91aa11

## もはや個別にmodel,controllerとか作らなくても良くない？全部まとめて作れるで

https://qiita.com/niisan-tokyo/items/9c799989cb535489f201

## 管理画面をlaravel-adminで作る

https://laravel-admin.org/docs/#/
https://tac-blog.tech/index.php/2018/09/29/laravel-admin-add-crud/

## 管理設定をmigrationできるようにseederに追加する

https://qiita.com/ntm718/items/5ea29ee70b50320352c4

## 基本のDBクエリビルド

https://www.ritolab.com/entry/93#aj_11_1

## Laravel debaggerを入れる

https://qiita.com/sutara79/items/9fd442a81001842aeba1

## apiResource

https://www.webopixel.net/php/1526.html

>純粋なAPIで使用するCRUDの場合はapiResourceを使用します。
Route::apiResource('users', 'UsersController');
これで、index,store,show,update,destroyが使用できるようになります。
複数のコントローラーをまとめて指定する場合はapiResourcesを使用します。
Route::apiResources([
    'tasks' => 'Api\TaskController',
    'users' => 'Api\UserController'
]);

### api用のデータ整形、リレーションデータの追加。

https://yuhodev.hatenablog.com/entry/2019/11/27/121500

## apiCollectionの作成

```
php artisan make:resource UserCollection
php artisan make:resource User
```

## JsonResouseに追加したい

```
    public function toArray($request)
    {
        $data = parent::toArray($request);

        $data["staff"] = StaffResource::collection($this->staff);
        $data["doctor"] = DoctorResource::collection($this->doctor);

        return $data;
        
    }
```

## apiのセキュリティ　自分のデータ以外は編集できてはいけない

Policyの設定を行う。

https://nakka-k.hatenablog.com/entry/2019/06/07/140758

```
$this->authorize('update', $user);
```

## APIで返却するJSONを共通フォーマットにしたい

https://waterfalls.hatenablog.com/entry/2019/08/24/012913

## Modelでバリデーションをする

https://qiita.com/kd9951/items/c06d107aa4018295aa25

## 中間テーブルを通した多対多リレーション

https://php-junkie.net/framework/laravel/many_to_many/

Tips: primarykeyを使わない場合
https://www.yuulinux.tokyo/15552/#i-5

## 多対多リレーション時のデータ修正・追加

例えばusers-> user_role -> roles というふうに
中間テーブルを経由してroleを管理している場合、roleを変更したい場合は

roleテーブルのidを配列で渡すだけで良い
roles = [1,2,3]

```
$user->roles()->sync($request->roles);
```

神か！！！

https://nextat.co.jp/staff/archives/200


この辺から自力で調べつつ、公式リファレンスを読めば大体構築イメージがつかめるようになってきました。

概ね3日でLaravelの基本は理解できたと言えます。
素晴らしいフレームワークですが、レイヤーも多いため、基本のSQLの知識も必要、PHPの基礎も。

やっぱ基礎って大事だな、と思いました。