Reputation: 406
I have a POST endpoint on my Laravel 5.5 API, I used postman to test my route and here is the problem. I want to send an array of the same kind of object, like this:
[
{
"name":"test",
"tag":"TEST"
},
{
"name":"test2",
"tag":"TEST_2"
}
]
But I can't manage to validate it properly.
in my controller, I have this:
$validator = Validator::make($requests->all(), [
'name' => 'required|string',
'tag' => 'required|string'
]);
if($validator->fails())
//Warn user for errors
I also tried with the simple
$this->validate($requests->all() .... )
I tried renaming the rules with '.name'
and '*.name'
but no success.
I tried replacing $request->all()
with $request->input()
but no success.
I also tried to loop over it but I get exceptions
foreach($request as $req){
$validator = Validator::make($req ....)
//rest of the code
}
On the other hand, I can retrieve the data like this $datas = $request->all()
and store them but there is no validation.
The only solution that seems to be working is naming my array:
{
"data" : [
{
"name":"test",
"tag":"TEST"
},
{
"name":"test2",
"tag":"TEST_2"
}
]
}
And then name the rules with 'data.*.name'
but this obliges the API user to parse the array.
Let suppose I have an array $array
which I want to store, I need to do
$arrayParsed = ['data' => $array]
and call the API with $arrayParsed
, which I think is a little redundant.
Is there a better way to handle the problem?
Upvotes: 12
Views: 21741
Reputation: 380
I was able to do this in laravel 6 like the following via App\Http\Requests CustomRequestClass
public function rules()
{
return [
'*.name' => 'required',
'*.tag' => 'required'
];
}
Upvotes: 7
Reputation: 1030
The approved answer works if your posting an array, however to take it a step further, I am needing to save multiple arrays. While that approach would work if I make two separate endpoints, what if I want to save everything inside one DB::transaction
?
Viola:
POST:
{
"array1": [
{ "key1": "string", "key2": 1 },
{ "key1": "string", key2": 0 }
],
"array2": [
{ "key3": "string", "key4": 1 },
{ "key3": "string", "key4": 0 }
]
}
SERVER:
$this->validate($request, [
'array1' => 'present|array',
'array2' => 'present|array',
'array1.*.key1' => 'required|string',
'array1.*.key2' => 'required|integer',
'array2.*.key3' => 'required|string',
'array2.*.key4' => 'required|integer'
]);
DB::transaction(function() use($request) {
foreach($request['array1'] as $x){
...do stuff here
};
});
Note: 'present|array'
accepts empty arrays whereas 'required|array'
would reject them.
Upvotes: 3
Reputation: 15457
You can try to circumvent the issue by first doing:
$data = [ 'data' => $requests->all() ];
Then you can use the rule you suggested:
$validator = Validator::make($data, [
'data.*.name' => 'required|string',
'data.*.' => 'required|string'
]);
Not the most elegant solution but it solves your issue...
Upvotes: 25