I'm building an API that takes in an array of 'additional_data' but I want some control over the fields that can be passed in.
Take the following JSON:
{
"name": "Joe Bloggs",
"additional_data": {
"type": "example",
"other_type": "example"
}
}
My current validation attempt:
return [
'name' => ['required'],
'additional_data.*' => ['sometimes', Rule::in(['type'])]
];
This always fails validation, what I'm looking for is to validate the key of the array so I can make sure the keys passed in are part of a 'whitelist'.
CodePudding user response:
To validate the keys of the additional_data array, you can use the exists rule and pass it a closure that checks if the key is in the whitelist. Here is an example:
return [
'name' => ['required'],
'additional_data.*' => ['sometimes', function ($attribute, $value, $fail) {
$whitelist = ['type'];
if (!in_array($attribute, $whitelist)) {
$fail("The $attribute is not allowed.");
}
}]
];
Alternatively, you can use the Rule::in rule with the array_keys function to get the keys of the additional_data array and check if they are in the whitelist. Here is an example:
return [
'name' => ['required'],
'additional_data' => ['sometimes', Rule::in(array_keys($whitelist))]
];
CodePudding user response:
What you do now is you try to validate content of additional_data.type
and additional_data.other_type
.
You can do this by adding a custom validator. For example
Validator::extend('check_additional_data_keys', function($attribute, $value, $parameters, $validator) {
return is_array($value) && array_diff(array_keys($value), ['type', 'other_type']) === 0);
});
and use it inside your current rules
return [
'name' => ['required'],
'additional_data' => ['check_additional_data_keys'],
'additional_data.*' => ['required', 'string'],
];
CodePudding user response:
Just specify your whitelist keys using the array
validation rule:
return [
'name' => 'required',
'additional_data' => [
'sometimes',
'array:type',
],
];