Both works, actually they execute the same code:
https://github.com/laravel/framework/blob/17e467cd132c6ccf60a02e00d3bdd4541a775c9f/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L543-L545
// Illuminate\Database\Eloquent\Concerns\HasAttributes
case 'array':
case 'json':
return $this->fromJson($value);
I prefer to use json over array when it is an array of objects, so the code communicates better its intent.
Regarding your expectation to see the input automatically converted to an array, that actually would allow a user to type a JSON string on a field where you expect a plain string (for example name or email) and make your code fail as you were not expecting an object.
If you want to use array-based validation on that input you could send it as an array from the frontend, it is more work to do, as I said that was the simple solution.
This link has a snippet on how to do this:
https://stackoverflow.com/a/28434829
For reference I will copy the code from the link above here:
var formData = new FormData;
var arr = ['this', 'is', 'an', 'array'];
for (var i = 0; i < arr.length; i++) {
formData.append('arr[]', arr[i]);
}
That way, when parsing the form input, PHP would populate the arr variable above as an array.
In your case, you could try something like this:
let barArray = [{item: 'one'}, {item: 'two'}];
let data = FormData();
barArray.forEach(function (element) {
data.append('foo[][item]', element.item);
})
this.$inertia.post('/upload', data);
This way PHP would parse foo as an array of associative-arrays, and you wouldn't need to use json_decode when assigning foo to a model.
A library I use in my JavaScript to make this use cases easier to handle is this one from Spatie:
https://github.com/spatie/form-backend-validation
It handles nested objects, array of objects and file uploads for you.