Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

rudrvij's avatar

Show Validation Errors in API Response

Hi, I am just starting with Laravel. I am building an API using Laravel framework. I created a form request and I am using that when I am doing a POST to my API. In the Form Request I specified the validation rules.

The validations are working. If there are any validation errors the data is not saved to the database. The problem is in this case the response would be the last successful response.

If there are validation erros, how do I return a response with error messages in the API?

Thanks for your help. -rudrvij

0 likes
14 replies
isaackearl's avatar

@rudrvij

In the App\Http\Controllers\Controller file (the base controller class), there is a function that builds the failed validation response.

    /**
     * Create the response for when a request fails validation.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  array  $errors
     * @return \Illuminate\Http\Response
     */
    protected function buildFailedValidationResponse(Request $request, array $errors)
    {
        if ($request->ajax() || $request->wantsJson()) {
            return new JsonResponse($errors, 422);
        }

        return redirect()->to($this->getRedirectUrl())
                        ->withInput($request->input())
                        ->withErrors($errors, $this->errorBag());
    }

You can extend Controller with your own controller class and override this method so it always builds the validation errors a certain way. For example this is how mine looks (I built an APIService which I use to return responses).


    /**
     * @inherited
     *
     * I'm overwriting this function because I just want to return a json response no matter what (this is an API)
     * @param RequestData|Request $request
     * @param array $errors
     * @return \Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     */
    protected function buildFailedValidationResponse(RequestData $request, array $errors)
    {
        return $this->api->setStatusCode(422)->respondWithError($errors);
//     return new JsonResponse($errors, 422);  // something like this? if you haven't built your own way to return json responses.
    }

So essentially you just want to override that function and tie it into how your application sends it's json responses.

rudrvij's avatar

Hi @isaackearl ,

I am having some problem with overriding the buildFailedValidationResponse method.

I have ApiController class that extends the Controller class.

<?php

    namespace App\Http\Controllers;

    use App\Http\Controllers\Controller;

    class ApiController extends Controller
    {

        protected function buildFailedValidationResponse(RequestData $request, array $errors)
        {
             return new JsonResponse($errors,422);
           
        }

    }

And I am inheriting this ApiController in my actual controller class.

<?php

namespace App\Http\Controllers\Method1;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Http\Controllers\ApiController;

class TestController extends ApiController
{
public function store(CreateTestRequest $request)
    {
        
        $title =  $request->input('title');
        $body =  $request->input('body');

        $newArticle = new \App\Entities\Article;
        $newArticle->Title = $title;
        $newArticle->Body = $body;

        if($newArticle->save())
        {
             return response()->json( ['data' =>'Success']);   
        }

        return response()->json( ['data' =>'Some error']);

    }
}

I keep getting an error when I have this method (buildFailedValidationResponse) in the ApiController class. If I comment it out I am not getting an error but it reverts back to the original way.

Any help is greatly appreciated.

Thanks -rudrvij

rudrvij's avatar

Any help would be greatly appreciated. I am new to Laravel and I am stuck at this point. All I am trying to do is override method in ValidateRequests. But it always picks the default behavior.

Please see my code in the previous post.

Thanks Vijay

rudrvij's avatar

@isaackearl I get 2 errors. I even get this when I do I get action where I am not using this validation.

1st Error

ReflectionException in Route.php line 280:
Class App\Http\Controllers\TestController does not exist

2nd Error

ErrorException in ApiController.php line 7:
Declaration of App\Http\Controllers\ApiController::buildFailedValidationResponse(App\Http\Controllers\Request $request, array $errors) should be compatible with App\Http\Controllers\Controller::buildFailedValidationResponse(Illuminate\Http\Request $request, array $errors)

Thanks -rudrvij

rudrvij's avatar

@isaackearl I did not notice the 2nd error before so I updated my APiController liek below:

<?php

    namespace App\Http\Controllers;

    use App\Http\Controllers\Controller;

    class ApiController extends Controller
    {

        protected function buildFailedValidationResponse(\Illuminate\Http\RequestData $request, array $errors)
        {
             return new JsonResponse($errors,422);
           
        }

    }

By doing this all my GET actions started working. But when there is a validation error, I am not seeing that in the POST action.

 public function store(CreateELRequest $request)
    {
        
        $title =  $request->input('title');
        $body =  $request->input('body');

        

        $newEssentialLearning = new \App\Entities\Article;
        $newEssentialLearning->Title = $title;
        $newEssentialLearning->Body = $body;

        if($newEssentialLearning->save())
        {
             return response()->json( ['data' =>'Success']);   
        }

        return response()->json( ['data' =>'Some error']);
    }
rudrvij's avatar

@isaackearl Couple of more updates,

I created one more controller with store method. In this method instead of using the FormRequest, I used the Request and calling validate explicitly.

It works if I use the "Request" and override in the ApiController method. There is a small error in the API Controller. I fixed it.

ApiController:

<?php

    namespace App\Http\Controllers;

    use App\Http\Controllers\Controller;

    class ApiController extends Controller
    {

        protected function buildFailedValidationResponse(RequestData $request, array $errors)
        {
             return $errors;
        }

    }

This works:

class AnotherController extends ApiController
{
public function store(Request $request)
    {
          $this->validate($request, [
        'title' => 'required',
        'body' => 'required',
    ]);

        $title =  $request->input('title');
        $body =  $request->input('body');

        $newArticle = new \App\Entities\Article;
        $newArticle->Title = $title;
        $newArticle->Body = $body;

       $newArticle->save();
        
        return "true";

    }
}

This does not work:

<?php

namespace App\Http\Controllers\Method1;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Http\Controllers\ApiController;

class TestController extends ApiController
{
public function store(CreateTestRequest $request)
    {
        
        $title =  $request->input('title');
        $body =  $request->input('body');

        $newArticle = new \App\Entities\Article;
        $newArticle->Title = $title;
        $newArticle->Body = $body;

      $newArticle->save();
    return "true";
      
    }
}

It does not work when I create a Form Request.

isaackearl's avatar
Level 10

@rudrvij So I was looking at my code to see what we do differently and I realized that I actually setup my own Request class to extend FormRequest. I override some of the functions to get things to work properly. Here is what my Request class looks like.

<?php namespace App\Http\Requests;

use API;
use Illuminate\Foundation\Http\FormRequest;

abstract class Request extends FormRequest
{

    /**
     * Get the proper failed validation response for the request.
     *
     * @param  array $errors
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function response(array $errors)
    {
        return API::setStatusCode(422)->respondWithError($errors);
    // yours might look more like this ->  return new JsonResponse($errors, 422);
    }

    /**
     * Get the response for a forbidden operation.
     *
     * @return \Illuminate\Http\Response
     */
    public function forbiddenResponse()
    {
        return API::respondForbidden();
    // yours might look more like this  -> return new JsonResponse('Forbidden', 403);
    }

}

Sorry I didn't mention this yesterday... I forgot that I changed BOTH my apicontroller and my request class to always return json responses etc.

rudrvij's avatar

hI @isaackearl

Thanks so much for your response. It worked. I really appreciate your help.

-rudrvij

isaackearl's avatar

@rudrvij I'm glad it worked!

It is not super important, but if you don't mind you can mark my answer as correct. So it shows this thread as "Answered".

Thanks!

Please or to participate in this conversation.