コードロード

エラー討伐

【Laravel】バリデーション失敗時に勝手にリダイレクトしないようにする(jsonを返させる)

課題

バリデーション失敗時に勝手に意図しないhtmlレスポンスを返す。

解決の過程

  1. ReactとLaravelで開発中に、データ更新時と登録時にたまに302レスポンスが返ってくる。
  2. コントローラまで処理が到達していない
  3. フォームリクエストで止まっているっぽい
  4. バリデーションに引っかかった時に302エラーを返しているよう
  5. ググったら、バリデーション失敗時は一個前のリクエストのページにリダイレクトしようとしているらしい。つまり、jsonで指定しているのにhtmlレスポンスになる。
  6. 勝手に前のページにリダイレクトしないようにしよう!

解決方法

Laravelはデフォルトで、バリデーション失敗時はリダイレクトされてHTMLレスポンスが返ってくるようになっているらしいので、このリダイレクトさせる処理をオーバーライドしてJSONが返ってくるようにする。

Illuminate\Foundation\Http\FormRequest クラスを継承した

app/Http/Requests/ApiRequest.phpを作成して、バリデーション失敗時の処理をオーバーライドさせる。

<?php

namespace App\Http\Requests;

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

class ApiRequest extends FormRequest
{

    /**
     * @Override
     * 勝手にリダイレクトさせない
     * @param  \Illuminate\Contracts\Validation\Validator  $validator
     */
    protected function failedValidation(Validator $validator)
    {
        $data = [
            'message' => 'The given data was invalid.',
            'errors'  => $validator->errors()->toArray(),
        ];

        throw new HttpResponseException(response()->json($data, 200));
    }
}

使用例

フォームリクエストを使用する際は、デフォルトの FormRequest を継承するのではなく、上記のオーバーライドした ApiRequest を継承するようにする。

そうすれば、バリデーションに失敗してもJSONを返すようになる。

<?php

use App\Http\Requests\ApiRequest;  // 追記
#use Illuminate\Foundation\Http\FormRequest;  // 使用せず

class SampleRequest extends ApiRequest  // 継承先をデフォルトのFormRequestから変更
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name' => ['required'],
        ];
    }
}

参考

qiita.com

Laravel5.8 FormRequestでバリデーション失敗時にJsonResponseを返す - Qiita

FormRequestのバリデーションエラー時のリダイレクト先をカスタマイズする - Qiita

https://webxreal.com/laravel-validation/

blog.capilano-fw.com