In Laravel 5.4, we created a class that all our requests for validation inherited because we needed to customize our response.
class APIRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return false;
}
/**
* Response on failure
*
* @param array $errors
* @return Response
*/
public function response(array $errors) {
$response = new ResponseObject();
$response->code = ResponseObject::BAD_REQUEST;
$response->status = ResponseObject::FAILED;
foreach ($errors as $item) {
array_push($response->messages, $item);
}
return Response::json($response);
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
//
];
}
}
A sample request that would extend this is shown below
class ResultsGetTermsRequest extends APIRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'school_id' => 'required|integer',
'student_id' => 'required|integer',
];
}
}
And then our sample response on failure would be
{
"status": "FAILED",
"code": "400",
"messages": [
[
"The school id field is required."
],
[
"The student id field is required."
]
],
"result": []
}
However, this doesn't work anymore with Laravel 5.5. I noticed they replaced with response method with failedValidation
. This however isn't returning any response when the request isn't validated. If I un-comment the print_r, it is something is returned. It seems the only line that is never executed is the return statement. What am I missing?
public function failedValidation(Validator $validator) {
$errors = (new ValidationException($validator))->errors();
$response = new ResponseObject();
$response->code = ResponseObject::BAD_REQUEST;
$response->status = ResponseObject::FAILED;
foreach ($errors as $item) {
array_push($response->messages, $item);
}
//print_r($response);
return Response::json($response);
}
I guess as per laravel upgrade guide we should return HttpResponseException
protected function failedValidation(Validator $validator)
{
$errors = $validator->errors();
$response = new ResponseObject();
$response->code = ResponseObject::BAD_REQUEST;
$response->status = ResponseObject::FAILED;
foreach ($errors as $item) {
array_push($response->messages, $item);
}
throw new HttpResponseException(response()->json($response));
}
If you want to do this from the FormRequest classes, potentially something like this:
protected function buildResponse($validator)
{
return response->json([
'code' => ResponseObject::BAD_REQUEST,
'status' => ResponseObject::FAILED,
'messages' => $validator->errors()->all(),
]);
}
protected function failedValidation(Validator $validator)
{
throw (new ValidationException($validator, $this->buildResponse($validator));
}
That would add that response you are building to the validation exception. When the exception handler tries to render this it will check if response
was set and if so it will use that response you passed instead of trying to convert the ValidationException to a response itself.
If you want 'ALL' validation exceptions to end up being rendered in this format I might just do this at the exception handler level, as the exception handler already has the ability to convert these exceptions to Json, so you could alter the format in the handler itself and basically not have to make any adjustments to the default FormRequest at all.
If you are in laravel 5+ you can easily achieve this, by overriding the invalid()
or invalidJson()
method in the App/Exceptions/Handler.php
file
In my case, I was developing an API and the api responses should be in a specific format, so I have added the following in the Handler.php
file.
/**
* Convert a validation exception into a JSON response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Validation\ValidationException $exception
* @return \Illuminate\Http\JsonResponse
*/
protected function invalidJson($request, ValidationException $exception)
{
return response()->json([
'code' => $exception->status,
'message' => $exception->getMessage(),
'errors' => $this->transformErrors($exception),
], $exception->status);
}
// transform the error messages,
private function transformErrors(ValidationException $exception)
{
$errors = [];
foreach ($exception->errors() as $field => $message) {
$errors[] = [
'field' => $field,
'message' => $message[0],
];
}
return $errors;
}
credit : Origianal Answer
来源:https://stackoverflow.com/questions/47690817/laravel-5-5-validation-change-format-of-response-when-validation-fails