38
votes

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?

5

5 Answers

37
votes

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;
31
votes

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."]
    }
}
6
votes

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
votes

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)
});
1
votes

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": ""
}