LaravelでAPI実装する際、バリデーション失敗したときにJSONレスポンスを返したいときのtips
環境
- PHP: 7.3.6
- Laravel 5.8.22
FormRequest とは
コントローラに書いたバリデーションの処理をバリデーション専用のクラスとして切り出したものになります。
バリデーションを分けることにより、コントローラにはバリデーション済みのリクエストが来るのでよりシンプルに記述できるメリットがあります。
バリデーションエラー時
デフォルトでは、getRedirectUrl()
メソッドが実行されてリダイレクトされ、HTMLレスポンスが返ってきます。
APIを実装するときにHTMLでレスポンスが返ってくると困るのでjsonで返ってくるように設定します。
ApiRequest
新しく app/Http/Requests/ApiRequest.php
を作成します。
<?php
namespace App\Http\Requests;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;
abstract class ApiRequest extends FormRequest
{
/**
* Handle a failed validation attempt.
*
* @param Validator $validator
* @return void
* @throw HttpResponseException
*/
protected function failedValidation(Validator $validator): void
{
$data = [
'data' => [],
'status' => 'error',
'summary' => 'Failed validation.',
'errors' => $validator->errors()->toArray(),
];
throw new HttpResponseException(response()->json($data, 422));
}
}
バリデーション失敗時の挙動を変えるには failedValidation()
をオーバーライドします。
全てのFormRequestクラスに実装するのは手間なので、 ApiRequest
という抽象クラスを用意します。
例: SignUpRequest
ApiRequest
を継承して実装していけばokです。
<?php
namespace App\Http\Requests;
class SignUpRequest extends ApiRequest
{
/**
* 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'],
];
}
}