Example: An Owner can have many Pets. A Pet has only one Owner.
But if I try to send invalid PATCH (array of Owners):
{
"data": {
"type": "pets",
"id": "1",
"attributes": {
"someValue": true
},
"relationships": {
"owner": {
"data": [{
"type": "owners",
"id": "1"
}]
}
}
}
}
(Type member is not a string, or is empty. at /var/www/vendor/cloudcreativity/laravel-json-api/src/Object/IdentifiableTrait.php:47)
or an invalid PATCH (Pet object)
{
"data": {
"type": "owners",
"id": "1",
"attributes": {
"someValue": true
},
"relationships": {
"pets": {
"data": {
"type": "pets",
"id": "1"
}
}
}
}
}
(Argument 1 passed to CloudCreativity\LaravelJsonApi\Object\ResourceIdentifier::fromArray() must be of the type array, string given)
I get an HTTP 500 (see errors above).
How or where to check if relationship is a valid Array (HasMany) or object (HasOne)?
Hi. If a pet has only one owner, the owner relationship should be to-one as follows:
{
"data": {
"type": "pets",
"id": "1",
"attributes": {
"someValue": true
},
"relationships": {
"owner": {
"data": {
"type": "owners",
"id": "1"
}
}
}
}
}
Then in reverse, an owner can have multiple pets i.e. to-many, so your other request should be:
{
"data": {
"type": "owners",
"id": "1",
"attributes": {
"someValue": true
},
"relationships": {
"pets": {
"data": [{
"type": "pets",
"id": "1"
}]
}
}
}
}
You're getting a 500 response because the code is expecting you to validate whether you've been sent the right kind of relationship - i.e. to-one or to-many. For example, your pets validator should have the following rule:
return [
'owner.type' => 'required|in:owners'
];
And your owners validator:
return [
'pets' => 'array',
'pets.*.type' => 'in:pets',
];
Personally, I don't think the validation by the developer should be explicitly specified here, because "the code" knows if it's a To-One or a To-Many relationship. I mean isn't it more convenient to include it in the Core/Package instead of defining same/similar rules for other resources?
And if I try to add "pets" => "array" rule, it is just ignored. But maybe it's my fault somewhere.
Yeah you're right... I think this is because historically there hasn't been a way to work this out, but as you say there is now. Will add it to the to-do list.
Note to self: add methods to the store interface to check whether a relation is to-one or to-many. This can be answered by detecting the interface of the adapter's relation. Need to work out what to do if the relation doesn't exist on the adapter - reject or allow? Presumably reject. Could also potentially store the inverse resource type on the relation, which would mean both the validator and the routing stack could gain access to it.
Closing in favour of the linked issue in the new package (above). This is entirely possible in the new package because the spec validators have access to field information (derived from the resource schema). I think I've probably already implemented rejecting invalid relationships in the new package - but I've just created the above issue to double check before marking it off as done.
Most helpful comment
Yeah you're right... I think this is because historically there hasn't been a way to work this out, but as you say there is now. Will add it to the to-do list.
Note to self: add methods to the store interface to check whether a relation is to-one or to-many. This can be answered by detecting the interface of the adapter's relation. Need to work out what to do if the relation doesn't exist on the adapter - reject or allow? Presumably reject. Could also potentially store the inverse resource type on the relation, which would mean both the validator and the routing stack could gain access to it.