【Laravel】バリデーション失敗時に勝手にリダイレクトしないようにする(jsonを返させる)
課題
バリデーション失敗時に勝手に意図しないhtmlレスポンスを返す。
解決の過程
- ReactとLaravelで開発中に、データ更新時と登録時にたまに302レスポンスが返ってくる。
- コントローラまで処理が到達していない
- フォームリクエストで止まっているっぽい
- バリデーションに引っかかった時に302エラーを返しているよう
- ググったら、バリデーション失敗時は一個前のリクエストのページにリダイレクトしようとしているらしい。つまり、jsonで指定しているのにhtmlレスポンスになる。
- 勝手に前のページにリダイレクトしないようにしよう!
解決方法
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'], ]; } }
参考
Laravel5.8 FormRequestでバリデーション失敗時にJsonResponseを返す - Qiita
FormRequestのバリデーションエラー時のリダイレクト先をカスタマイズする - Qiita