I am working on a Project, of which the structure is based on Laravel and, my situation is to return a Validation Error JSON Format or Auto-Carried in Flashed Session (stored in $errors variable) given by a Request.
To strategize the JSON response format, I actually work with Handler Exception. So, I implement a custom ApiValidationErrorException class for Json Format, which looks like as bellow:
<?php namespace App\Exceptions; use Exception; use Illuminate\Http\JsonResponse; use Illuminate\Validation\ValidationException; use Symfony\Component\HttpFoundation\Response; class ApiValidationErrorException extends ValidationException { public function render($request): JsonResponse { return new JsonResponse([ // This is the array that you will return in case of an error. // You can put whatever you want inside. 'message' => 'There were some errors', 'status' => false, 'additionalThings' => 'Some additional things', 'errors' => $this->validator->errors()->getMessages(), ], Response::HTTP_UNPROCESSABLE_ENTITY); } }
then, call this custom class in Handler->register function, it looks like
<?php namespace App\Exceptions; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Validation\ValidationException; use Throwable; class Handler extends ExceptionHandler { /** * Register the exception handling callbacks for the application. */ public function register(): void { $this->renderable(function (ValidationException $exception, $request) { throw ApiValidationErrorException::withMessages( $exception->validator->getMessageBag()->getMessages() ); }); $this->reportable(function (Throwable $e) { // }); } }
However, this register throws a problem for returning errors on web request. Instead of displaying messages in HTML which is generated from blade templates, it returns a JSON response because the renderable method always throws ApiValidationErrorException format.
So, this definitely needs a if else statement
here to control the response properly.
So, the conditional statement detect the request whether it is RESTful Request or Form Request. Alright, Laravel provides a method on request Object name wantsJson()
, which checks the client request sends Accept=application/json
in Header
. So to use it, we have to set Accept=application/json
in Header
otherwise, this method returns false always. Then, I ask myself, is there any options to check API request? . Right, I search and search ... it comes up with a method, $request->is('api/*'). Utimately, the register()
method looks like
public function register(): void { $this->renderable(function (ValidationException $exception, $request) { if ($request->wantsJson() || $request->is('api/*')) { throw ApiValidationErrorException::withMessages( $exception->validator->getMessageBag()->getMessages() ); } return null; }); $this->reportable(function (Throwable $e) { // }); }
I hope this post could help some of you strategize the reponse format in such a situation
Top comments (0)