Aoi
Aoi

Reputation: 1045

REST API in Laravel when validating the request

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?

Upvotes: 50

Views: 109856

Answers (7)

Rafiul Islam
Rafiul Islam

Reputation: 11

    $validator = Validator::make($request->all(), [
        'code' => 'required',
    ]);

    if ($validator->fails()) {
        $errorMessage = $validator->errors()->first();
        $response = [
            'status'  => false,
            'message' => $errorMessage,
        ];
        return response()->json($response, 401);
    }

Upvotes: 1

NicoHood
NicoHood

Reputation: 1123

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.

Upvotes: 1

bhupendraosd
bhupendraosd

Reputation: 639

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;

Upvotes: 53

Nishant
Nishant

Reputation: 311

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

Upvotes: 5

mwal
mwal

Reputation: 3113

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

Upvotes: 3

zak.http
zak.http

Reputation: 316

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.

Upvotes: 10

Jason Lewis
Jason Lewis

Reputation: 18665

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

Upvotes: 31

Related Questions