How to set custom response for selected Request class in Laravel 5.5
Asked Answered
B

2

18

I'm trying to use Laravel validation to generate custom error message, however I'm unable to find the function I should be overriding.

Route: POST:/entries/ uses EntryController@store which uses EntryStoreRequest to perform validation.

EntryStoreRequest

namespace App\Api\V1\Requests;

class EntryStoreRequest extends ApiRequest
{
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'message' => [
                'string',
                'required',
                'max:65535',
            ],
            'code' => [
                'string',
                'max:255',
                'nullable'
            ],
            'file' => [
                'string',
                'max:255',
                'nullable'
            ],
            'line' => [
                'string',
                'max:255',
                'nullable'
            ],
            'stack' => [
                'string',
                'max:65535',
                'nullable'
            ]
        ];
    }
}

ApiRequest

namespace App\Api\V1\Requests;

use Illuminate\Foundation\Http\FormRequest;

abstract class ApiRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }
}

The errors are currently returned as:

{
    "message": "The given data was invalid.",
    "errors": {
        "message": [
            "The message field is required."
        ]
    }
}

I want to format them as:

{
    "data": [],
    "meta: {
        "message": "The given data was invalid.",
        "errors": {
            "message": [
                "The message field is required."
            ]
        }
}

How can I achieve this within the ApiRequest class?

Bloody answered 10/10, 2017 at 15:3 Comment(0)
B
45

If you want to customize validation response only for selected Request class, you need to add failedValidation() message to this class:

protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
    $response = new JsonResponse(['data' => [], 
             'meta' => [
                'message' => 'The given data is invalid', 
                'errors' => $validator->errors()
             ]], 422);

    throw new \Illuminate\Validation\ValidationException($validator, $response);
}

This way you don't need to change anything in Handler and have this custom response only for this single class.

And if you want to change format globally for all responses you should add to app\Exceptions\Handler.php file the following method:

protected function invalidJson($request, ValidationException $exception)
{
    return response()->json([
             'data' => [], 
             'meta' => [
                'message' => 'The given data is invalid', 
                'errors' => $exception->errors()
             ]
             ], $exception->status);
}

You can read about this also in Upgrade guide in Exception Format section

Baghdad answered 10/10, 2017 at 15:21 Comment(3)
Won't that define such responses for all validations? What can I do to define above mentioned format only for given Request class?Bloody
Silly me - I've been looking at this method before, and even overrode it in ApiRequest class as protected function failedValidation(Validator $validator) to which I've gotten a Class App\Api\V1\Requests\EntryStoreRequest does not exist which doesn't really explain anything. Your answer provided me with an explanation to that as well :) Thanks!Bloody
Thanks for the answer. It works for me. Really helpful. Thanks @MarcinNabiałekLeishmaniasis
L
0

For those who don't want to use JsonResponse, here was what I did for mine

protected function failedValidation(Validator $validator) {
        // if you want, log something here with $this->validationData(), $validator->errors()
        
        $response = redirect($this->getRedirectUrl())
            ->with('var1', 'my var 1') // custom flash variable to send if needed
            ->with('var2', 'my var 2')
            ->withErrors($validator)
            ->withInput();
        
        throw new ValidationException($validator, $response);
    }
Litmus answered 5/11, 2021 at 1:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.