I am making an API and i want return the array of errors with a format as the one that $validator->errors();
generates when i validate the request by the manual way. But i cant manipulate the response. I wanna find thhe correct way to make it.
This could be done in Laravel 5.4 with the formatErrors
method and including the Illuminate\Contracts\Validation\Validator
class in the FormRequest class but for version 5.5 it does not work. I do not know how to do it.
This is my Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\ProductRequest;
use Illuminate\Validation\Rule;
use App\Product;
class ProductController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(ProductRequest $request)
{
$products = Product::where('code', 'LIKE', '%'.$request->input('search').'%')
->where('name', 'LIKE', '%'.$request->input('search').'%')
->paginate(10);
$products->withPath($request->fullUrl());
return $products;
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(ProductRequest $request)
{
$product = new Product($request->validated());
$product->save();
return response('', 201);
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$product = Product::find($id);
return response($product, 200);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(ProductRequest $request, $id)
{
$product = Product::find($id);
$product->fill($request->validated());
$product->save();
return response('', 200);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$product = Product::find($id);
$product->delete();
return response('', 204);
}
}
This is mi FormRequest class
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class ProductRequest extends FormRequest
{
/**
* 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()
{
switch($this->method())
{
case 'GET':
{
return [
'code' => 'string',
'name' => 'string',
];
} break;
case 'POST':
{
return [
'code' => 'required|unique:Products,code',
'name' => 'required',
'description' => 'required',
'quantity' => 'required|min:0',
'price' => 'required|numeric',
'extemp' => [
Rule::in(['tax', 'free']),
]
];
} break;
case 'PUT':
{
return [
'code' => 'unique:products,code,'.$this->route('product'),
'name' => 'string:min:1',
'description' => 'string|min:1',
'quantity' => 'integer|min:0',
'price' => 'numeric',
'extemp' => [
Rule::in(['tax', 'free']),
],
];
} break;
case 'PATCH': break;
case 'DELETE': break;
default:
{
return [];
} break;
}
}
/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function messages()
{
return [
//Product
'code.required' => 'El :attribute es obligatorio.',
'code.unique' => 'El :attribute ya se encuentra registrado.',
'name.required' => 'El :attribute es obligatorio.',
'name.min' => 'El :attribute es obligatorio.',
'description.required' => 'El :attribute es obligatorio.',
'description.min' => 'El :attribute es obligatorio.',
'quantity.required' => 'La :attribute es obligatoria.',
'quantity.integer' => 'La :attribute debe ser un número entero.',
'quantity.min' => 'La :attribute debe ser al menos :min.',
'price.required' => 'El :attribute es obligatorio.',
'price.numeric' => 'El :attribute debe ser un valor numérico.',
'extemp.in' => 'El :attribute seleccionado es inválido.',
];
}
public function attributes(){
return [
'code' => 'código',
'name' => 'nombre',
'description' => 'descripción',
'quantity' => 'cantidad',
'price' => 'precio',
'extemp' => 'exento',
];
}
}
The Response what i have:
{
"message": "The given data was invalid.",
"errors": {
"code": [
"El código es obligatorio."
],
"name": [
"El nombre es obligatorio."
],
"description": [
"El descripción es obligatorio."
],
"quantity": [
"La cantidad es obligatoria."
],
"price": [
"El precio es obligatorio."
]
}
}
The Response what i want (with $validator->errors();
)
[
"El código es obligatorio.",
"El nombre es obligatorio.",
"El descripción es obligatorio.",
"La cantidad es obligatoria.",
"El precio es obligatorio."
]
You have to override the failedValidation()
method and issue the exception with the response what you want.
So, you need to use Illuminate\Contracts\Validation\Validator
and Illuminate\Http\Exceptions\HttpResponseException
in the RequestForm class, and override the failedValidation()
method:
protected function failedValidation(Validator $validator) {
throw new HttpResponseException(response()->json($validator->errors()->all(), 422));
}
For this Need to override failedValidation()
function in your Request file.
protected function failedValidation(Validator $validator)
{
throw new HttpResponseException(response()->json([
'errors' => $validator->errors(),
'status' => false
], 422));
}
To make it work use
these namespaces:
For laravel 5.4 and above:
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exceptions\HttpResponseException;
description here
Below laravel 5.4:
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exception\HttpResponseException;
description here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With