FuelPHPしか触ったことないPGがLaravelで実装してみた所感

###はじめに
※FuelからLaravelに乗り換えて、まだシステムの実装途中でこの記事を書いているため、ところどころおかしなことがあると思いますが目をつむってくだされば幸いです。

###なぜFuelからlaravelに乗り換えたのか
以前に保守を行っていたシステムでちょっと古いFuelとPHPを使ってました。
そろそろPHPのバージョンを上げなきゃなって時にまさかのFuelの開発が止まっており、最新のPHPのバージョンでFuelが動くのかわからない状態に…
その時は別の優先度が高い案件が入り、ペンディングになっている間にFuelPHPのバージョンがリリース（1.8.2）されわりと新しいPHPのバージョン（7.3系）に対応したため事なきを得ました。
しかしながら、古いPHPのサポート終了は次々とやってきます。なので今後なにか新しいものを作る場合は学習コストを払ってでも、更新が頻繁でモダン的、使用しているユーザーも多くドキュメントが豊富なフレームワークを使おうということになり、Laravelを選択しました。

###とりあえず触ってみたが…
PHPのフレームワークはFuelしか触ったことがなく、すでに動いているシステムがあったためフレームワークの特徴などがつかみやすい状況でした。
何もない状態から触ったことのないフレームワークでシステムを組んでいくというのは初めてのことで、とりあえずAPIが動くようにいろいろいじってみました。

簡単なControllerを作成し、ルーティングをして実行。無事返却値を返すことができました。
じゃあ、ここからORACLEをつないでと思ったところ、まさかのLaravelでORACLEをサポートしていないという事実が…
更新が頻繁でモダンということで選択したLaravelでしたが、もう少し調査をしてから使用するフレームワークを決めるべきでした。
今回は幸いに公式ではないですがORACLEにつなぐためのライブラリが提供されていましたので、それを使用して難を逃れました。

###公式のドキュメント、記事を探して…
ちょっとやりたいことがありLaravelのドキュメントを見に行きました。Fuelの時は公式のドキュメントにCoreクラスのリクエストパラメータの説明、返却値の説明が割と細かく書いてあったため、その感覚でLaravelも書いてあるだろうと見に行きましたが、結果はどこに書いてあるかわからない、みつけても書いてない…
自分の調べ方見方が悪かったのかもしれないのですが、全然見つからない。
仕方なくQiita等の個人ブログで情報収集に、シェア率が高いフレームワークなのでいろいろ出てくるだろうと思ったが結果はなし。
Fuelの時はかなり古いものでしたが何かしらの記事は出てきたのに、全然ない。あっても公式のドキュメント以上の情報がほぼなし。
今人気のあるフレームワークなので、記事いっぱいあるでしょと高を括った結果がこれでした。

###まだ触り始めて１か月弱…
同じPHPのフレームワークだし、実装と学習同時にいけるでしょと考えていた自分を叱りたいです。
やはりすでに動いているシステムがあるのないのとじゃ、理解の速度に差が出ますね。
今回は画面などは作らず、APIのみの形なのでまだ何とかなってるような感じがします。
このままだとただのブログになってしまっているので、少しテックブログっぽく今調べた技術面も載せておきたいと思います。

###APIの共通処理
APIの共通処理を作成する際に、Fuelのbeforeやafterのようなことがlaravelでもできないか調べていました。
やり方としては、app/Providersディレクトリ配下にファイルを作成し、Illuminate\Support\ServiceProviderを継承させます

```php:TestResponseServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
class TestResponseServiceProvider extends ServiceProvider
{
}
```
bootファンクションを作成し、そこに成功用、失敗用、エラー用の返却値を作成します

```php:TestResponseServiceProvider.php
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;

class TestResponseServiceProvider extends ServiceProvider
{
    public function boot() {
        //成功時
        Response::macro('success', function ($data = [], $extraData = []) {
            return response()->json([
                'success'  => true,
                'response' => $data,
                'extra'    => $extraData
            ]);
        });

        //失敗時
        Response::macro('error', function ($errMsg = '', array $errors = []) {
            return response()->json([
                'success'  => false,
                'errMsg'   => $errMsg,
                'errors'   => $errors
            ]);
        });

        //エラー時
        Response::macro('fatalError', function ($errMsg, array $errors = [], $status = ResponseStatus::HTTP_INTERNAL_SERVER_ERROR) {
            return response()->json([
                'success'  => false,
                'status'   => $status,
                'errMsg'   => $errMsg,
                'errors'   => $errors
            ], $status);
        });
    }

}
```
こちらを作成した後にconfig/app.phpのprovidersの中に下記の内容を記載します

```php:app.php
'providers' => [
App\Providers\TestResponseServiceProvider::class,
]
```
APIの返却時に下記のように記載すると返却値の共通化ができます。

```php:api.php
return response()->success($result);
```
### バリデーション処理をきれいに
APIの作成を行っているので、バリデーション処理は必須です。Laravelでのバリデーションは下記のような記述で可能です。

```PHP:api.php
public function test(Request $request) {
        $validator = Validator::make($request->all(), [
            'AAAAA' => 'required|string|max:64',
            'BBBBB' => ['required','numeric','regex:/^[0-9]{4}(0[1-9]|1[0-2])$/'],
        ]);

        if ($validator->fails()) {
            return response()->json([
                'status' => 400,
                'errors' => $validator->errors()
            ], 400);
        }
}
```
この形をAPIごとに書いていくのはきれいじゃないなと思い、なにかきれいにまとめたりできないかと調べたところ
FormRequestを使えば、別クラスにバリデーションを記載でき、ソースがすっきりすることがわかったので試してみました。
バリデーションクラスの書き方としては、App\Http配下にRequestsフォルダを作成し、バリデーション用のクラスを作成します。
作成したクラスにはIlluminate\Foundation\Http\FormRequestを継承させます。

```PHP:TestRequests.php
<?php

namespace App\Http\Requests;

use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;

class TestRequestsextends FormRequest
{
    /**
     * @return bool
     */
    public function authorize() {
        return true;
    }

    /**
     * @return array
     */
    public function rules() {
        return [
        ];
    }
}
```
authorizeは認証、rulesはバリデーションルールを記載します。
今回はバリデーションルールのみを記述するので、authorizeにはtrueを返すようにしています。
rulesの中に、バリデーションルールを記述すると、そのルールでバリデーションを行ってくれます。

```PHP:TestRequests.php
    public function rules() {
        return [
            'AAAAAA' => 'required|string|max:64',
            'BBBBBB' => ['required','numeric','regex:/^[0-9]{4}(0[1-9]|1[0-2])$/']
        ];
    }
```
さらにfailedValidationをオーバライドすることにより、エラー時の返却値も記述することもできます。

```PHP:TestRequests.php
    protected function failedValidation(Validator $validator) {
        $res = response()->json([
            'status' => 400,
            'errors' => $validator->errors(),
        ], 400);
        throw new HttpResponseException($res);
    }
```
ここまでの記述が終わったらAPIの$requestの型を先ほどつくったTestRequestsに変更すれば、自動でバリデーションを行ってくれます。
バリデーション部分がなくなったため、APIファイルには処理のみを記載すればよくなるので、すっきりすると思います。

```PHP:api.php
use App\Http\Requests\TestRequests;
public function test(TestRequests $request) {
        //処理を記載する
}
```
また、バリデーションメッセージもLaravelは提供してくれているのですが、英語のメッセージでわかりにくい場合は日本語化することも可能です。
まずこの[github](https://github.com/Laravel-Lang/lang/tree/master/locales/ja)から日本語化ファイルをダウンロードし、resources/lang配下にjaというフォルダを作成しコピーします。

```
resources
    ∟ lang
        ∟ ja
            ∟ auth.php
              passwords.php
              validation-attributes.php
              ja.json
              validation-inline.php
              validation.php
              pagination.php
```
コピーが完了したら、config/app.phpのlocaleをjaに書き換えれば日本語化完了です。

```php:config/app.php
    /*
    |--------------------------------------------------------------------------
    | Application Locale Configuration
    |--------------------------------------------------------------------------
    |
    | The application locale determines the default locale that will be used
    | by the translation service provider. You are free to set this value
    | to any of the locales which will be supported by the application.
    |
    */

    'locale' => 'ja',
```
設定されている日本語のメッセージが合わない場合は、validation.phpの中身を修正すれば好みのメッセージに変更することが可能です。
また、customの中にバリデーションを行う引数ごとにメッセージを記載することも可能です。

```php:resources/lang/ja/validation.php
    'custom'               => [
        'AAAAA' => [
            'required' => 'AAAAAは必須です',
        ],
    ]
```
### 参考資料
　　出典：[PHP][Laravel] APIのResponseデータをカスタムしてシステム内でレスポンス形式をルール化・共通化する　（最終閲覧日：2021年11月8日）
　　  　　https://waterfalls.hatenablog.com/entry/2019/08/24/012913
　　出典：Laravel 8.x HTTPレスポンス　（最終閲覧日：2021年11月8日）
　　  　　https://readouble.com/laravel/8.x/ja/responses.html
　　出典：Laravel 8.x バリデーション　（最終閲覧日：2021年11月8日）
　　  　　https://readouble.com/laravel/8.x/ja/validation.html
　　出典：Laravelを使ったAPI開発でController内のバリデーションをFormRequestに抽出して幸せになろう　（最終閲覧日：2021年11月8日）
　　  　　https://nakka-k.hatenablog.com/entry/2019/06/04/191906
　　出典：【laravel】FormRequestによるバリデーション　（最終閲覧日：2021年11月8日）
　　  　　https://qiita.com/gone0021/items/249e99338ff414fc5737