9

Quick question. Would it be possible to changes the JSON validation response of laravel? This is for a custom API that I am building in Laravel.

Validation process

$validation = $this->validate( 
    $request, [
        'user_id' => 'required', 
    ]);

The response shows up like this in json

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

Preferable it would become something like this.

{
    "common:" [
        "status": "invalid",
        "message": "Param xxxx is required",
    ],
}

What would be the best way to changes this? Is it even possible?

Thank you.

5
  • 1
    why you want to change this ? you can manage it in front end. as laravel returns all errors at once for an elements. and in your format it is just one. Commented Feb 15, 2019 at 4:35
  • Its for a custom api function that returns json. The meaning is to get a certain template with json format Commented Feb 15, 2019 at 4:36
  • also reformat your expected result from current resonse what you need exactly? and yes please explain why you need this ? Commented Feb 15, 2019 at 4:37
  • can you show your code where you returns laravel validation messages? Commented Feb 15, 2019 at 4:38
  • Right now laravel does the validations by itself the following way. $validation = $this->validate( $request, [ 'user_id' => 'required', ] ); Commented Feb 15, 2019 at 4:39

3 Answers 3

6

I was searching for an answer to this and I think I found a better way. There is an exception handler in a default Laravel app - \App\Exceptions\Handler - and you can override the invalidJson method:

<?php

namespace App\Exceptions;

use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Validation\ValidationException;

class Handler extends ExceptionHandler
{
    // ...

    protected function invalidJson($request, ValidationException $exception)
    {
        $errors = [];
        foreach ($exception->errors() as $field => $messages) {
            foreach ($messages as $message) {
                $errors[] = [
                    'code' => $field,
                    'message' => $message,
                ];
            }
        }
    
        return response()->json([
            'error' => $errors,
        ], $exception->status);
    }
}
Sign up to request clarification or add additional context in comments.

Comments

5

You can do this, and it will be reflected globally. Navigate to below folder and use Controller.php app/Http/Controllers

use Illuminate\Http\Request;

Write below method in Controller.php and change response as you want.

public function validate(
    Request $request,
    array $rules,
    array $messages = [],
    array $customAttributes = [])
{
    $validator = $this->getValidationFactory()
        ->make(
            $request->all(),
            $rules, $messages,
            $customAttributes
        );
    if ($validator->fails()) {
        $errors = (new \Illuminate\Validation\ValidationException($validator))->errors();
        throw new \Illuminate\Http\Exceptions\HttpResponseException(response()->json(
            [
                'status' => false,
                'message' => "Some fields are missing!",
                'error_code' => 1,
                'errors' => $errors
            ], \Illuminate\Http\JsonResponse::HTTP_UNPROCESSABLE_ENTITY));
    }
}

I have tried it with Laravel 5.6, maybe this is useful for you.

4 Comments

Thank you, I was looking for this. What if I only want to show one error? is this also possible? Like the validations are user_id, and username, but I they are both missing I only want to show an error for the user_id and not the username.
@WesleySchravendijk, you can use bail rule to the attribute.
I have tried the bail function, but somehow it doesn't work in laravel 5.7. For example; 'user_id' => 'bail|required',
it does not work using laravel 8, I added the code in Controller.php and nothing worked
1

@Dev Ramesh solution is still perfectly valid for placing inline within your controller.

For those of you looking to abstract this logic out into a FormRequest, FormRequest has a handy override method called failedValidation. When this is hit, you can throw your own response exception, like so...

/**
 * When we fail validation, override our default error.
 *
 * @param ValidatorContract $validator
 */
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
    $errors = $this->validator->errors();

    throw new \Illuminate\Http\Exceptions\HttpResponseException(
        response()->json([
            'errors' => $errors,
            'message' => 'The given data was invalid.',

            'testing' => 'Whatever custom data you want here...',
        ], 422)
    );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.