LaravelのFormRequestバリデーション結果を json API で返す | luftgarden

LaravelのFormRequestバリデーション結果を json API で返す

公開日: 2026年2月26日最終更新日: 2026年2月26日

バリデーション結果が json にならないケース

例えば、会員を新規追加するAPIのエンドポイントがあるとします。

[POST] https://example.com/api/users
Route::resource( 'users', 'Api\UsersController' )->only( ['store'] );

Controllerは以下のような状態です。

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\StoreUserRequest;
use App\Http\Resources\UserResource;
use App\User;

class UsersController extends Controller
{
    /**
     * 会員追加
     *
     * @param StoreUserRequest $request
     * @return User
     */
    public function store( StoreUserRequest $request )
    {
        return User::create( $request->only( ['name'] ) ); 
    }
}

FormRequestクラスは以下の状態です。

$ php artisan make:request StoreUserRequest
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreUserRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => 'required',
        ];
    }

    public function messages()
    {
        return [
            'name.required' => 'お名前を入力してください。',
        ];
    }
}

上記APIを叩いた際、「お名前を入力してください」と
json 形式でエラーメッセージを返却したい場合を考えます。

このままの状態でAPIを叩いても素直にエラーレスポンスが返りません。
(welcomeページのHTMLが返ってきたりする)

原因と対応

バリデーション失敗時にFormRequestクラス内でリダイレクトが発生することが原因のようです。
参考: Laravel5.1.xでAPIを作る際に気になっていたことを調べました – Qiita

バリデーション失敗時にも json 形式で結果を返すように対応していきます。

Laravel5.4以前

FormRequest::response() をオーバーライドすることで対応可能なようです。

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\JsonResponse; // 追加

class StoreUserRequest extends FormRequest
{
    /**
     * [override]
     * バリデーション失敗時ハンドリング
     *
     * @param array $errors
     * @return JsonResponse
     */
    public function response( array $errors )
    {
        $response = [
            'data' => [],
            'status' => 'NG',
            'summary' => 'Failed validation.',
            'errors' => $errors,
        ];
        return new JsonResponse( $response, 422 );
    }
}

Laravel5.5以降

FormRequest::response() は廃止されているため、
代わりにFormRequest::failedValidation() をオーバーライドすることで対応します。

<?php

namespace App\Http\Requests;

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

class StoreUserRequest extends FormRequest
{
    /**
     * [override] 
     * バリデーション失敗時ハンドリング
     *
     * @param Validator $validator
     * @throw HttpResponseException
     * @see FormRequest::failedValidation()
     */
    protected function failedValidation( Validator $validator )
    {
        $response['data'] = [];
        $response['status'] = 'NG';
        $response['summary'] = 'Failed validation.';
        $response['errors'] = $validator->errors()->toArray();

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

実行結果

エンドポイントを叩いて json レスポンスが返却されればOKです。
以下の画像は POSTMAN のキャプチャです。

API用のリクエストクラスを作成する

APIを作成する場合はレスポンス形式を統一することになると思うので、
下記のような抽象クラスを作成しておいたほうがよいでしょう。

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

参考記事