LaravelでAPIのValidationエラーをどこで返すか問題
PHP/Laravel・AWS中心のWebエンジニア / テックリード。10年超の開発経験をもとに副業・業務委託のご依頼を受け付けています。
LaravelでAPIのValidationエラーをどこで返すか問題
2019年7月11日

個人的見解

  • Handler でハンドリングして返すのが正しいと思う。
  • そこ以外でハンドリングするとなると多分 trait を FormRequest で use するとかそんな方法になってしまう。それはそれで正しいとは思うけども本当に正しいのだろうか?と考えた結果Handler.phpで返すことに決めた

実処理

app/Exceptions/Handler.php

<?php
declare(strict_types=1);

// 省略

class Handler extends ExceptionHandler
{
    /**
    * @const string
    */
    const ROUTE_PREFIX = 'api';

    // 省略
    public function render($request, Exception $exception): void
    {
        if(collect(explode('/', $request->route()->getPrefix()))->first() === self::ROUTE_PREFIX ) {
            $this->apiReqponse($exception);
        }
    }

    // 省略
    private function apiResponse(Exception $exception): void
    {
        if ($exception instanceof ValidationException) {
            $this->throw($exception->errors(), 400);
        }

        // 他のexceptionを羅列することが可能
    }

    private function throw(array $errorMessage, int $code): void
    {
        throw new HttpResponseException(
            response()->json(
                [
                    'status' => 'fail',
                    'code' => $code,
                    'error_message' => $errorMessage
                ],
                $code
            )
        );
    }
}

返却値

  • 返却内容は、ぶっちゃけエラーとわかりかつ、フロント側で処理が行いやすいものならなんでもいいかなと思う。

{
    'status': 'fail,
    'code': 400,
    'error_message': {
        'field name': [
            'エラーです'
        ]
    }
}

余談

こっからは余談ですが、API の実装をしている基本的な返却形式は統一すべきだとおもってますし実際それは、スタンダードな考えだと思っています。今回Validationエラーに関して Handler でハンドリングを行うようにしたことによって統一できました。さらにいうとこれでテストの実装に関してはも形式が同じになったことにより楽になりました。

またこのハンドリングを他のExceptionにも対応させることによって利用者側に明確にどんなエラーかをこちらの意図で伝えることが可能になります。なのでどのレイヤーでも対応が可能になるかと。

似たように正常の処理に関しても trait にまとめることによってレスポンスに関しては、どこにどのように定義すべきかがわかるようになりますね。

trait を利用し getter, setter の要領で形式を統一可能です。

次回・・・・・・

気分が乗ったら実装例を晒したいと思います。