28

It's the first time i am using validation in laravel. I am trying to apply validation rule on below json object. The json object name is payload and example is given below.

payload = {
  "name": "jason123",
  "email": "[email protected]",
  "password": "password",
  "gender": "male",
  "age": 21,
  "mobile_number": "0322 8075833",
  "company_name": "xyz",
  "verification_status": 0,
  "image_url": "image.png",
  "address": "main address",
  "lattitude": 0,
  "longitude": 0,
  "message": "my message",
  "profession_id": 1,
  "designation_id": 1,
  "skills": [
    {
      "id": 1,
      "custom" : "new custom1"
    }
   ]
}

And the validation code is like below, for testing purpose i am validating name as a digits. When i executed the below code, the above json object is approved and inserted into my database. Instead, it should give me an exception because i am passing name with alpha numeric value, am i doing something wrong:

public function store(Request $request)
{

    $this->validate($request, [
        'name' => 'digits',
        'age' => 'digits',
        ]);
}
1
  • you should use integer to accept only numbers or alpha for only alphabetic characters Commented May 16, 2017 at 12:15

6 Answers 6

39

Please try this way

use Validator;

public function store(Request $request)
{
    //$data = $request->all();
    $data = json_decode($request->payload, true);
    $rules = [
        'name' => 'digits:8', //Must be a number and length of value is 8
        'age' => 'digits:8'
    ];

    $validator = Validator::make($data, $rules);
    if ($validator->passes()) {
        //TODO Handle your data
    } else {
        //TODO Handle your error
        dd($validator->errors()->all());
    }
}

digits:value

The field under validation must be numeric and must have an exact length of value.

Sign up to request clarification or add additional context in comments.

4 Comments

if ($validator->fails()) { return response()->json($validator->messages(), 200); } Is a better way to handle the messages
@rchatburn Yes. I'm using this way for API.
@rchatburn, heh... longtime since you commented this, but I think it should return 422 instead of 200... regards.
A 400 is better than a 422 as 422 is WebDAV specific. See stackoverflow.com/questions/16133923/…
13

I see some helpful answers here, just want to add - my preference is that controller functions only deal with valid requests. So I keep all validation in the request. Laravel injects the request into the controller function after validating all the rules within the request. With one small tweak (or better yet a trait) the standard FormRequest works great for validating json posts.

Client example.js

var data = {first: "Joe", last: "Dohn"};
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST",'//laravel.test/api/endpoint');
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send(JSON.stringify(data));

project/routes/api.php

Route::any('endpoint', function (\App\Http\Requests\MyJsonRequest $request){
    dd($request->all());
});

app/Http/Requests/MyJsonRequest.php (as generated by php artisan make:request MyJsonRequest)

<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyJsonRequest extends FormRequest{

    public function authorize(){
        return true;//you'll want to secure this
    }

    public function rules(){
        return [
            'first' => 'required',
            'last'  => 'required|max:69',
        ];
    }

    //All normal laravel request/validation stuff until here
    //We want the JSON...
    //so we overload one critical function with SOMETHING LIKE this
    public function all($keys = null){
        if(empty($keys)){
            return parent::json()->all();
        }

        return collect(parent::json()->all())->only($keys)->toArray();
    }
}

1 Comment

Working perfectly on Laravel 8
3

Your payload should be payload: { then you can do

$this->validate($request->payload, [
    'name' => 'required|digits:5',
    'age' => 'required|digits:5',
    ]);

or if you are not sending the payload key you can just use $request->all()

2 Comments

I am sending json object with the key "payload" but i get error when i try to access it like this $request->payload error:validate() must be an instance of Illuminate\Http\Request, string given.
@MTA In that case use Quỳnh Nguyễn answer and replace $request->all() with $request->payload
2

Following the example of @tarek-adam, in Laravel 9 it would be:

<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class MyJsonRequest extends FormRequest{

    public function authorize(){
        return true;//you'll want to secure this
    }

    public function rules(){
        return [
            'first' => 'required',
            'last'  => 'required|max:69',
        ];
    }

    //All normal laravel request/validation stuff until here
    //We want the JSON...
    public function validationData()
    {
        return $this->json()->all();
    }
}

Comments

1
 $request->merge([
            'meta_data' => !is_null($request->meta_data) ? json_encode($request->meta_data) : null
        ]);

validator = Validator::make($request->all(), [
      'meta_data' => 'nullable|json'
        ]);

Comments

0

Use the Validator factory class instead using validate method derived from controller's trait. It accepts array for the payload, so you need to decode it first

\Validator::make(json_decode($request->payload, true), [
    'name' => 'digits',
    'age' => 'digits',
]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.