50

I'm currently trying out on how to build a RESTful API with Laravel and I'm currently in the process of creating a new user. This is just a test and I'm getting some result when trying to validate the request using validation in Laravel; here is the result:

enter image description here

I've been trying to create a new one by this code:

public function store() { $validation = Validator::make(Request::all(),[ 'username' => 'required|unique:users, username', 'password' => 'required', ]); if($validation->fails()){ } else{ $createUser = User::create([ 'username' => Request::get('username'), 'password' => Hash::make(Request::get('password')) ]); } } 

but then I don't know how to return the error in validation. But it keeps on giving me that HTML as showed in the image when I was trying to do the if with validation->fails(). Is there a way to get the validation in JSON format?

7 Answers 7

53

these code will help you, working for me.

$response = array('response' => '', 'success'=>false); $validator = Validator::make($request->all(), $rules); if ($validator->fails()) { $response['response'] = $validator->messages(); } else { //process the request } return $response; 
Sign up to request clarification or add additional context in comments.

3 Comments

This answer deserves more credit. I've tried all solutions and this one gave me the right messages in Laravel 5.2 atleast.
Laravel does this out the box for XMLHttpRequest - for AJAX I think it should do this also for API requests as Laravel is API oriented. I wonder if is possible to find a hack to make the API calls XMLHttpRequest. Would that be too weird?
How to do this similar implementation using Laravel Request Class ?
31

You should probably return errors (which is an instance of Illuminate\Support\MessageBag) and encode that. A MessageBag instance allows you to convert it directly to its JSON representation.

$errors = $validation->errors(); return $errors->toJson(); 

Now not to toot my own horn but I've recently developed a RESTful API package for Laravel which does all of this for you and all you need to do is throw a simple exception. See my dingo/api package and the Wiki on returning errors. Basically, instead of returning the errors you would throw an exception.

throw new Dingo\Api\Exception\StoreResourceFailedException('Could not create a new user.', $validation->errors()); 

It would be represented by the following JSON.

{ "message": "Could not create a new user.", "errors": { "username": ["The username is already in use."] } } 

3 Comments

ill try your package after i make this work. the thing is it returns the if($validation->fails()){ } in to html in my terminal so you would end up returning some html then it wont read the next lines of codes. that my theory on what happening to it..
fount it. i have to specify the content type. i found the answer here stackoverflow.com/questions/7172784/…
You should toot your horn. Dingo is a very popular package now. So thank you for making it!
10

Laravel provides out of the box a validation method that you can call from your Controller.

if you check the Laravel Controller abstract class you will find it uses a trait called ValidatesRequests

 abstract class Controller extends BaseController { use AuthorizesRequests, DispatchesJobs, ValidatesRequests; } 

So you can use a method $this->validate(Request $request, array $rules); as you long as your controller class extends the Controller

the full method declaration is

public function validate(Request $request, array $rules, array $messages = [], array $customAttributes = []) { $validator = $this->getValidationFactory()->make($request->all(), $rules, $messages, $customAttributes); if ($validator->fails()) { $this->formatValidationErrors($validator); } } 

If The $validator fails, the method will throw an error depending on the request type, if it is ajax (in this case you should include in the request headers (Accept application/json) it will return a JSON response containing the validation errors.

3 Comments

+1 This should be the accepted answer; reuses controller code and formats errors automatically AJAX requests.
but it will redirect you to another page, I think I will redirect you back to the previous page those using it via Rest API are not suitable unless you handle the exception by yourself. cause it will throw an exception and the one who catches the exception will redirect you to the last page with the error message that works fine with traditional form, not Rest API. Maybe some error's middleware will help or just catch manually using make
Update on my last comment, if your header is requesting to accept JSON Laravel will not redirect and return a JSON message. So make sure the header accepts JSON instead of all. This is documented in Laravel's official doc . You may also create middleware to change the request header so Laravel will only return JSON on the route which you attach the middleware. laravel.com/docs/10.x/…
5

There are many ways to get a validator response first is to get an all validation error at the same time i.e you will get a response like below

 $validator = \Validator::make($request->all(), [ 'username' => 'required|unique:users, username', 'password' => 'required', ]); if ($validator->fails()) { $responseArr = CustomHelper::returnRespArr(""); $responseArr['message'] = $validator->errors();; $responseArr['token'] = ''; return response()->json($responseArr, Response::HTTP_BAD_REQUEST); } 

Response you will get is:

{ "status": false, "data": [], "message": { "username": [ "The username field is required." ], "password": [ "The password field is required." ] }, "is_valid": 0, "token": "" } 

The second way to get a validation response. In this, you will get a one validator error a time.

 if ($validator->fails()) { $responseArr = CustomHelper::returnRespArr(""); $responseArr['message'] = $validator->messages()->first();; $responseArr['token'] = ''; return response()->json($responseArr,Response::HTTP_BAD_REQUEST); } 

The response you will get

{ "status": false, "data": [], "message": "The username field is required.", "is_valid": 0, "token": "" } 

Comments

3

For laravel 5.5 and up, see docs: AJAX Requests & Validation

TL;DR: On failed validation a json response with a 422 is returned along with the validation error messages. It took me a bit of time to find those validation errors in the response object, so to see the error messages if you're using axios, try this in your browser console:

axios.post('/api/your-route-here') .then(response => { console.log(response.data); }).catch(error => { console.log(error.response.data.errors) }); 

Comments

1

I am using Laravel 9.x and found a quite simple way to validate errors with REST APIs:

public function store(Request $request) { $input = $request->all(); $validator = Validator::make($input, [ 'title' => 'required|string|max:50' ]); // Will return an error, if validation fails. // https://laravel.com/api/9.x/Illuminate/Foundation/Validation/ValidatesRequests.html#method_validateWith $this->validateWith($validator, $request); // Only use the properties that were validated. $input = $validator->validated(); // Create a new event model, with the data provided. $event = Event::create($input); return new EventResource($event); } 

In order to return a json error message, make sure to set the Accept header of the client to application/json. I make the mistake to not set this in my debug client, so I only saw html/xml messages.

You can also force the output to json.

1 Comment

how to convert this into laravel form validation request and still use Validator in controller
1
 $validator = Validator::make($request->all(), [ 'code' => 'required', ]); if ($validator->fails()) { $errorMessage = $validator->errors()->first(); $response = [ 'status' => false, 'message' => $errorMessage, ]; return response()->json($response, 401); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.