Repository navigation
Denormalize IRI to resource #5128
Replies: 11 comments
What exception? I think that you should set the groups accordingly and avoid to denormalize the group in that case. |
The exception was UPDATE: when I execute PUT request on User resource, this exception doesn't happen because there is |
|
Okay so this is definitely due too constructor arguments. Would it be possible to add default values to the constructor parameters to see if it fixes the bug? Indeed, when doing the IRI denormalization, the group name isn't needed. @Nek- did you experience this as well? |
|
I just had made test repository to reproduce the issue https://github.com/ghettovoice/api-platform/tree/issue-2123. Full stack trace: {
"@context": "/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "Cannot create an instance of App\\Entity\\Group from serialized data because its constructor requires parameter \"name\" to be present.",
"trace": [
{
"namespace": "",
"short_class": "",
"class": "",
"type": "",
"function": "",
"file": "/srv/api/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php",
"line": 389,
"args": []
},
{
"namespace": "Symfony\\Component\\Serializer\\Normalizer",
"short_class": "AbstractNormalizer",
"class": "Symfony\\Component\\Serializer\\Normalizer\\AbstractNormalizer",
"type": "->",
"function": "instantiateObject",
"file": "/srv/api/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php",
"line": 143,
"args": [
[
"array",
[
[
"string",
"/groups/1"
]
]
],
[
"string",
"App\\Entity\\Group"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
],
"cache_key": [
"string",
"3109355309ab720c2fd4470e519cd894"
]
}
],
[
"object",
"ReflectionClass"
],
[
"array",
[
[
"string",
"username"
],
[
"string",
"group"
]
]
],
[
"string",
"json"
]
]
},
{
"namespace": "Symfony\\Component\\Serializer\\Normalizer",
"short_class": "AbstractObjectNormalizer",
"class": "Symfony\\Component\\Serializer\\Normalizer\\AbstractObjectNormalizer",
"type": "->",
"function": "instantiateObject",
"file": "/srv/api/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php",
"line": 244,
"args": [
[
"array",
[
[
"string",
"/groups/1"
]
]
],
[
"string",
"App\\Entity\\Group"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
],
"cache_key": [
"string",
"3109355309ab720c2fd4470e519cd894"
]
}
],
[
"object",
"ReflectionClass"
],
[
"array",
[
[
"string",
"username"
],
[
"string",
"group"
]
]
],
[
"string",
"json"
]
]
},
{
"namespace": "Symfony\\Component\\Serializer\\Normalizer",
"short_class": "AbstractObjectNormalizer",
"class": "Symfony\\Component\\Serializer\\Normalizer\\AbstractObjectNormalizer",
"type": "->",
"function": "denormalize",
"file": "/srv/api/vendor/api-platform/core/src/Serializer/AbstractItemNormalizer.php",
"line": 128,
"args": [
[
"string",
"/groups/1"
],
[
"string",
"App\\Entity\\Group"
],
[
"string",
"json"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
],
"cache_key": [
"string",
"3109355309ab720c2fd4470e519cd894"
]
}
]
]
},
{
"namespace": "ApiPlatform\\Core\\Serializer",
"short_class": "AbstractItemNormalizer",
"class": "ApiPlatform\\Core\\Serializer\\AbstractItemNormalizer",
"type": "->",
"function": "denormalize",
"file": "/srv/api/vendor/api-platform/core/src/Serializer/ItemNormalizer.php",
"line": 43,
"args": [
[
"string",
"/groups/1"
],
[
"string",
"App\\Entity\\Group"
],
[
"string",
"json"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
],
"cache_key": [
"string",
"3109355309ab720c2fd4470e519cd894"
]
}
]
]
},
{
"namespace": "ApiPlatform\\Core\\Serializer",
"short_class": "ItemNormalizer",
"class": "ApiPlatform\\Core\\Serializer\\ItemNormalizer",
"type": "->",
"function": "denormalize",
"file": "/srv/api/vendor/symfony/serializer/Serializer.php",
"line": 177,
"args": [
[
"string",
"/groups/1"
],
[
"string",
"App\\Entity\\Group"
],
[
"string",
"json"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
],
"cache_key": [
"string",
"3109355309ab720c2fd4470e519cd894"
]
}
]
]
},
{
"namespace": "Symfony\\Component\\Serializer",
"short_class": "Serializer",
"class": "Symfony\\Component\\Serializer\\Serializer",
"type": "->",
"function": "denormalize",
"file": "/srv/api/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php",
"line": 370,
"args": [
[
"string",
"/groups/1"
],
[
"string",
"App\\Entity\\Group"
],
[
"string",
"json"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
],
"cache_key": [
"string",
"3109355309ab720c2fd4470e519cd894"
]
}
]
]
},
{
"namespace": "Symfony\\Component\\Serializer\\Normalizer",
"short_class": "AbstractNormalizer",
"class": "Symfony\\Component\\Serializer\\Normalizer\\AbstractNormalizer",
"type": "->",
"function": "instantiateObject",
"file": "/srv/api/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php",
"line": 143,
"args": [
[
"array",
{
"group": [
"string",
"/groups/1"
]
}
],
[
"string",
"App\\Entity\\User"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
],
"cache_key": [
"string",
"3109355309ab720c2fd4470e519cd894"
]
}
],
[
"object",
"ReflectionClass"
],
[
"array",
[
[
"string",
"username"
],
[
"string",
"group"
]
]
],
[
"string",
"json"
]
]
},
{
"namespace": "Symfony\\Component\\Serializer\\Normalizer",
"short_class": "AbstractObjectNormalizer",
"class": "Symfony\\Component\\Serializer\\Normalizer\\AbstractObjectNormalizer",
"type": "->",
"function": "instantiateObject",
"file": "/srv/api/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php",
"line": 244,
"args": [
[
"array",
{
"group": [
"string",
"/groups/1"
]
}
],
[
"string",
"App\\Entity\\User"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
],
"cache_key": [
"string",
"3109355309ab720c2fd4470e519cd894"
]
}
],
[
"object",
"ReflectionClass"
],
[
"array",
[
[
"string",
"username"
],
[
"string",
"group"
]
]
],
[
"string",
"json"
]
]
},
{
"namespace": "Symfony\\Component\\Serializer\\Normalizer",
"short_class": "AbstractObjectNormalizer",
"class": "Symfony\\Component\\Serializer\\Normalizer\\AbstractObjectNormalizer",
"type": "->",
"function": "denormalize",
"file": "/srv/api/vendor/api-platform/core/src/Serializer/AbstractItemNormalizer.php",
"line": 128,
"args": [
[
"array",
{
"username": [
"string",
"test"
],
"group": [
"string",
"/groups/1"
]
}
],
[
"string",
"App\\Entity\\User"
],
[
"string",
"json"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
],
"cache_key": [
"string",
"3109355309ab720c2fd4470e519cd894"
]
}
]
]
},
{
"namespace": "ApiPlatform\\Core\\Serializer",
"short_class": "AbstractItemNormalizer",
"class": "ApiPlatform\\Core\\Serializer\\AbstractItemNormalizer",
"type": "->",
"function": "denormalize",
"file": "/srv/api/vendor/api-platform/core/src/Serializer/ItemNormalizer.php",
"line": 43,
"args": [
[
"array",
{
"username": [
"string",
"test"
],
"group": [
"string",
"/groups/1"
]
}
],
[
"string",
"App\\Entity\\User"
],
[
"string",
"json"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
],
"api_denormalize": [
"boolean",
true
]
}
]
]
},
{
"namespace": "ApiPlatform\\Core\\Serializer",
"short_class": "ItemNormalizer",
"class": "ApiPlatform\\Core\\Serializer\\ItemNormalizer",
"type": "->",
"function": "denormalize",
"file": "/srv/api/vendor/symfony/serializer/Serializer.php",
"line": 177,
"args": [
[
"array",
{
"username": [
"string",
"test"
],
"group": [
"string",
"/groups/1"
]
}
],
[
"string",
"App\\Entity\\User"
],
[
"string",
"json"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
]
}
]
]
},
{
"namespace": "Symfony\\Component\\Serializer",
"short_class": "Serializer",
"class": "Symfony\\Component\\Serializer\\Serializer",
"type": "->",
"function": "denormalize",
"file": "/srv/api/vendor/symfony/serializer/Serializer.php",
"line": 128,
"args": [
[
"array",
{
"username": [
"string",
"test"
],
"group": [
"string",
"/groups/1"
]
}
],
[
"string",
"App\\Entity\\User"
],
[
"string",
"json"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
]
}
]
]
},
{
"namespace": "Symfony\\Component\\Serializer",
"short_class": "Serializer",
"class": "Symfony\\Component\\Serializer\\Serializer",
"type": "->",
"function": "deserialize",
"file": "/srv/api/vendor/api-platform/core/src/EventListener/DeserializeListener.php",
"line": 95,
"args": [
[
"array",
{
"username": [
"string",
"test"
],
"group": [
"string",
"/groups/1"
]
}
],
[
"string",
"App\\Entity\\User"
],
[
"string",
"json"
],
[
"array",
{
"collection_operation_name": [
"string",
"post"
],
"operation_type": [
"string",
"collection"
],
"api_allow_update": [
"boolean",
false
],
"resource_class": [
"string",
"App\\Entity\\User"
],
"request_uri": [
"string",
"/users"
],
"uri": [
"string",
"http://localhost:8080/users"
]
}
]
]
},
{
"namespace": "ApiPlatform\\Core\\EventListener",
"short_class": "DeserializeListener",
"class": "ApiPlatform\\Core\\EventListener\\DeserializeListener",
"type": "->",
"function": "onKernelRequest",
"file": null,
"line": null,
"args": [
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent"
],
[
"string",
"kernel.request"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher"
]
]
},
{
"namespace": "",
"short_class": "",
"class": "",
"type": "",
"function": "call_user_func",
"file": "/srv/api/vendor/symfony/event-dispatcher/Debug/WrappedListener.php",
"line": 104,
"args": [
[
"array",
[
[
"object",
"ApiPlatform\\Core\\EventListener\\DeserializeListener"
],
[
"string",
"onKernelRequest"
]
]
],
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent"
],
[
"string",
"kernel.request"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Debug\\TraceableEventDispatcher"
]
]
},
{
"namespace": "Symfony\\Component\\EventDispatcher\\Debug",
"short_class": "WrappedListener",
"class": "Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener",
"type": "->",
"function": "__invoke",
"file": "/srv/api/vendor/symfony/event-dispatcher/EventDispatcher.php",
"line": 212,
"args": [
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent"
],
[
"string",
"kernel.request"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\EventDispatcher"
]
]
},
{
"namespace": "Symfony\\Component\\EventDispatcher",
"short_class": "EventDispatcher",
"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
"type": "->",
"function": "doDispatch",
"file": "/srv/api/vendor/symfony/event-dispatcher/EventDispatcher.php",
"line": 44,
"args": [
[
"array",
[
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
],
[
"object",
"Symfony\\Component\\EventDispatcher\\Debug\\WrappedListener"
]
]
],
[
"string",
"kernel.request"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent"
]
]
},
{
"namespace": "Symfony\\Component\\EventDispatcher",
"short_class": "EventDispatcher",
"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
"type": "->",
"function": "dispatch",
"file": "/srv/api/vendor/symfony/event-dispatcher/Debug/TraceableEventDispatcher.php",
"line": 141,
"args": [
[
"string",
"kernel.request"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent"
]
]
},
{
"namespace": "Symfony\\Component\\EventDispatcher\\Debug",
"short_class": "TraceableEventDispatcher",
"class": "Symfony\\Component\\EventDispatcher\\Debug\\TraceableEventDispatcher",
"type": "->",
"function": "dispatch",
"file": "/srv/api/vendor/symfony/http-kernel/HttpKernel.php",
"line": 125,
"args": [
[
"string",
"kernel.request"
],
[
"object",
"Symfony\\Component\\HttpKernel\\Event\\GetResponseEvent"
]
]
},
{
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "HttpKernel",
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"type": "->",
"function": "handleRaw",
"file": "/srv/api/vendor/symfony/http-kernel/HttpKernel.php",
"line": 66,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
],
[
"integer",
1
]
]
},
{
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "HttpKernel",
"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
"type": "->",
"function": "handle",
"file": "/srv/api/vendor/symfony/http-kernel/Kernel.php",
"line": 188,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
],
[
"integer",
1
],
[
"boolean",
true
]
]
},
{
"namespace": "Symfony\\Component\\HttpKernel",
"short_class": "Kernel",
"class": "Symfony\\Component\\HttpKernel\\Kernel",
"type": "->",
"function": "handle",
"file": "/srv/api/public/index.php",
"line": 37,
"args": [
[
"object",
"Symfony\\Component\\HttpFoundation\\Request"
]
]
}
]
}
If make |
It's one of the reasons I dislike the denormalization via constructor and why I wasn't in favor of implementing this :p. We don't retrieve the name because we already know the group |
|
It's just was unexpected for me that fetching by IRI works in update request (that is mentioned in docs) and doesn't works in create requests. Anyway I rewrite this part using DTOs and custom persister/data provider. |
|
@ghettovoice your work around looks great! and honestly seems like it would be like the only proper way to handle this? I can't imagine adding this check comes with any major performance issues for denormalization in general. Because regardless if you are setting via constructor or by public property, the string value needs to be denormalized. |
|
Hi @ragboyjr , |
|
@ghettovoice Thanks, i also needed to add a compiler pass to update the API platform item normalizer to use the custom one. |
|
Is there a better way to do this yet with API Platform? I made a copy+paste gist based on code from @ghettovoice above, for anyone that runs into this issues too https://gist.github.com/VeryStrongFingers/866f755b558b2b4f6d47389c8fd51816 |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Hi, I noticed that ItemNormalizer doesn't support denormalizing of IRI string. I have an issue, probably related to #2036, with deserializing entity with type hinted constructor. For example if we have User and Group entities which are exposed as API resources:
Sending POST to
/usersrequest with payload:This leads to exception when symfony AbstractNormalizer trying to denormalize
$groupargument to theGroupresource from string/groups/123456. Actually ItemNormalizer is used to denormalize IRI string but it doesn't trying to load resource from IRI converter like it does for array withidfield here .As a workaround currently I'm using extended
ItemNormalizerI'm using the latest
api-platform/core:2.3All reactions