Skip to content

V3.0 POST using Dto : output / provider : denormalize error  #5101

Description

@FredCastel

API Platform version(s) affected: 3.0

Description
I am using Dto input and ouput on my entities, (operations : get / post)
when I try to post an entity where there is a ManyToOne relation with the other one
I received the error message "The input data is misformatted." raised by \api-platform\core\src\Serializer\AbstractItemNormalizer.php : denormalize function

when I remove the get ouput Dto on the linked entity there is no error, POST result in a success

composer.lock

    "packages": [
        {
            "name": "api-platform/core",
            "version": "v3.0.2",

How to reproduce

Bank entity : that will be created using POST

src\Entity\Bank.php

<?php

#[ORM\Entity(repositoryClass: BankRepository::class)]
#[ApiResource(
    normalizationContext: ['iri_only' => true]
)]
#[Get(
    output : BankOutput::class,
    provider: BankItemProvider::class
)]
#[GetCollection()]
#[Post(
    input : BankInput::class,
    processor: BankProcessor::class
)]
#[Patch(
    input : BankInput::class,
    output : BankOutput::class,
    processor: BankProcessor::class
)]
#[Put(
    controller: NotFoundAction::class
)]
#[Delete(
    processor: BankProcessor::class
)]
class Bank
{
...
    #[ORM\ManyToOne(targetEntity: ImageBank::class)]
    #[ORM\JoinColumn(nullable: true)]
    private ?ImageBank $image = null;
...

the Image entity that I want to set on a bank using POST

src\Entity\ImageBank.php

<?php

#[ORM\Entity]
#[ApiResource(
    normalizationContext: ['iri_only' => true],
)]
#[Get(
    output : ImageBankOutput::class, //when I remove that that's work fine
    provider: ImageBankItemProvider::class //when I remove that that's work fine
)]
#[GetCollection()]
class ImageBank extends Image
{ ....

is there an other way to use Dto with entity relation ? is it a bug ?
thanks for your help,

Additional Context

api get are working fine on bank and image models
api bank post work fine when I don"t set image relation "image": "\/api\/image_banks\/1",
api bank post work fine when I remove the Dto ouput and provider from the image get operation
api bank post don't work when I try to set a image using it's IRI, when Dto exist on image get operation

POST body https://localhost/api/banks

{
  "name": "new post api",
  "state": "enabled",
  "startDate": "2022-10-23T15:55:59.157Z",
  "endDate": "2022-10-23T15:55:59.157Z",
  "image": "\/api\/image_banks\/1",
  "url": "https:\/\/mabanque.fortuneo.fr",
  "bic": "FTNOFRP1",
  "country": "FR"
}

result

{
	"@context": "\/api\/contexts\/Error",
	"@type": "hydra:Error",
	"hydra:title": "An error occurred",
	"hydra:description": "The input data is misformatted.",
	"trace": [
		{
			"namespace": "",
			"short_class": "",
			"class": "",
			"type": "",
			"function": "",
			"file": "\/srv\/app\/vendor\/api-platform\/core\/src\/Serializer\/AbstractItemNormalizer.php",
			"line": 178,
			"args": []
		},
		{
			"namespace": "ApiPlatform\\Serializer",
			"short_class": "AbstractItemNormalizer",
			"class": "ApiPlatform\\Serializer\\AbstractItemNormalizer",
			"type": "->",
			"function": "denormalize",
			"file": "\/srv\/app\/vendor\/api-platform\/core\/src\/Serializer\/ItemNormalizer.php",
			"line": 70,
			"args": [
				[
					"array",
					{
						"name": [
							"string",
							"new post api"
						],
						"state": [
							"string",
							"enabled"
						],
						"startDate": [
							"string",
							"2022-10-23T15:55:59.157Z"
						],
						"endDate": [
							"string",
							"2022-10-23T15:55:59.157Z"
						],
						"image": [
							"string",
							"\/api\/image_banks\/1"
						],
						"url": [
							"string",
							"https:\/\/mabanque.fortuneo.fr"
						],
						"bic": [
							"string",
							"FTNOFRP1"
						],
						"country": [
							"string",
							"FR"
						]
					}
				],
				[
					"string",
					"App\\Entity\\Bank"
				],
				[
					"string",
					"json"
				],
				[
					"array",
					{
						"resource_class": [
							"string",
							"App\\Dto\\BankInput"
						],
						"skip_null_values": [
							"boolean",
							true
						],
						"iri_only": [
							"boolean",
							false
						],
						"request_uri": [
							"string",
							"\/api\/banks"
						],
						"uri": [
							"string",
							"https:\/\/localhost\/api\/banks"
						],
						"output": [
							"null",
							null
						],
						"api_allow_update": [
							"boolean",
							false
						]
					}
				]
			]
		},
		{
			"namespace": "ApiPlatform\\Serializer",
			"short_class": "ItemNormalizer",
			"class": "ApiPlatform\\Serializer\\ItemNormalizer",
			"type": "->",
			"function": "denormalize",
			"file": "\/srv\/app\/vendor\/symfony\/serializer\/Serializer.php",
			"line": 238,
			"args": [
				[
					"array",
					{
						"name": [
							"string",
							"new post api"
						],
						"state": [
							"string",
							"enabled"
						],
						"startDate": [
							"string",
							"2022-10-23T15:55:59.157Z"
						],
						"endDate": [
							"string",
							"2022-10-23T15:55:59.157Z"
						],
						"image": [
							"string",
							"\/api\/image_banks\/1"
						],
						"url": [
							"string",
							"https:\/\/mabanque.fortuneo.fr"
						],
						"bic": [
							"string",
							"FTNOFRP1"
						],
						"country": [
							"string",
							"FR"
						]
					}
				],
				[
					"string",
					"App\\Entity\\Bank"
				],
				[
					"string",
					"json"
				],
				[
					"array",
					{
						"operation_name": [
							"string",
							"_api_\/banks.{_format}_post"
						],
						"operation": [
							"object",
							"ApiPlatform\\Metadata\\Post"
						],
						"resource_class": [
							"string",
							"App\\Entity\\Bank"
						],
						"skip_null_values": [
							"boolean",
							true
						],
						"iri_only": [
							"boolean",
							false
						],
						"request_uri": [
							"string",
							"\/api\/banks"
						],
						"uri": [
							"string",
							"https:\/\/localhost\/api\/banks"
						],
						"input": [
							"array",
							{
								"class": [
									"string",
									"App\\Dto\\BankInput"
								],
								"name": [
									"string",
									"BankInput"
								]
							}
						],
						"output": [
							"null",
							null
						],
						"api_allow_update": [
							"boolean",
							false
						]
					}
				]
			]
		},
		{
			"namespace": "Symfony\\Component\\Serializer",
			"short_class": "Serializer",
			"class": "Symfony\\Component\\Serializer\\Serializer",
			"type": "->",
			"function": "denormalize",
			"file": "\/srv\/app\/vendor\/symfony\/serializer\/Serializer.php",
			"line": 151,
			"args": [
				[
					"array",
					{
						"name": [
							"string",
							"new post api"
						],
						"state": [
							"string",
							"enabled"
						],
						"startDate": [
							"string",
							"2022-10-23T15:55:59.157Z"
						],
						"endDate": [
							"string",
							"2022-10-23T15:55:59.157Z"
						],
						"image": [
							"string",
							"\/api\/image_banks\/1"
						],
						"url": [
							"string",
							"https:\/\/mabanque.fortuneo.fr"
						],
						"bic": [
							"string",
							"FTNOFRP1"
						],
						"country": [
							"string",
							"FR"
						]
					}
				],
				[
					"string",
					"App\\Entity\\Bank"
				],
				[
					"string",
					"json"
				],
				[
					"array",
					{
						"operation_name": [
							"string",
							"_api_\/banks.{_format}_post"
						],
						"operation": [
							"object",
							"ApiPlatform\\Metadata\\Post"
						],
						"resource_class": [
							"string",
							"App\\Entity\\Bank"
						],
						"skip_null_values": [
							"boolean",
							true
						],
						"iri_only": [
							"boolean",
							false
						],
						"request_uri": [
							"string",
							"\/api\/banks"
						],
						"uri": [
							"string",
							"https:\/\/localhost\/api\/banks"
						],
						"input": [
							"array",
							{
								"class": [
									"string",
									"App\\Dto\\BankInput"
								],
								"name": [
									"string",
									"BankInput"
								]
							}
						],
						"output": [
							"null",
							null
						],
						"api_allow_update": [
							"boolean",
							false
						]
					}
				]
			]
		},
		{
			"namespace": "Symfony\\Component\\Serializer",
			"short_class": "Serializer",
			"class": "Symfony\\Component\\Serializer\\Serializer",
			"type": "->",
			"function": "deserialize",
			"file": "\/srv\/app\/vendor\/api-platform\/core\/src\/Symfony\/EventListener\/DeserializeListener.php",
			"line": 78,
			"args": [
				[
					"array",
					{
						"name": [
							"string",
							"new post api"
						],
						"state": [
							"string",
							"enabled"
						],
						"startDate": [
							"string",
							"2022-10-23T15:55:59.157Z"
						],
						"endDate": [
							"string",
							"2022-10-23T15:55:59.157Z"
						],
						"image": [
							"string",
							"\/api\/image_banks\/1"
						],
						"url": [
							"string",
							"https:\/\/mabanque.fortuneo.fr"
						],
						"bic": [
							"string",
							"FTNOFRP1"
						],
						"country": [
							"string",
							"FR"
						]
					}
				],
				[
					"string",
					"App\\Entity\\Bank"
				],
				[
					"string",
					"json"
				],
				[
					"array",
					{
						"operation_name": [
							"string",
							"_api_\/banks.{_format}_post"
						],
						"operation": [
							"object",
							"ApiPlatform\\Metadata\\Post"
						],
						"resource_class": [
							"string",
							"App\\Entity\\Bank"
						],
						"skip_null_values": [
							"boolean",
							true
						],
						"iri_only": [
							"boolean",
							false
						],
						"request_uri": [
							"string",
							"\/api\/banks"
						],
						"uri": [
							"string",
							"https:\/\/localhost\/api\/banks"
						],
						"input": [
							"array",
							{
								"class": [
									"string",
									"App\\Dto\\BankInput"
								],
								"name": [
									"string",
									"BankInput"
								]
							}
						],
						"output": [
							"null",
							null
						],
						"api_allow_update": [
							"boolean",
							false
						]
					}
				]
			]
		},
		{
			"namespace": "ApiPlatform\\Symfony\\EventListener",
			"short_class": "DeserializeListener",
			"class": "ApiPlatform\\Symfony\\EventListener\\DeserializeListener",
			"type": "->",
			"function": "onKernelRequest",
			"file": "\/srv\/app\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php",
			"line": 270,
			"args": [
				[
					"object",
					"Symfony\\Component\\HttpKernel\\Event\\RequestEvent"
				],
				[
					"string",
					"kernel.request"
				],
				[
					"object",
					"Symfony\\Component\\EventDispatcher\\EventDispatcher"
				]
			]
		},
		{
			"namespace": "Symfony\\Component\\EventDispatcher",
			"short_class": "EventDispatcher",
			"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
			"type": "::",
			"function": "Symfony\\Component\\EventDispatcher\\{closure}",
			"file": "\/srv\/app\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php",
			"line": 230,
			"args": [
				[
					"object",
					"Symfony\\Component\\HttpKernel\\Event\\RequestEvent"
				],
				[
					"string",
					"kernel.request"
				],
				[
					"object",
					"Symfony\\Component\\EventDispatcher\\EventDispatcher"
				]
			]
		},
		{
			"namespace": "Symfony\\Component\\EventDispatcher",
			"short_class": "EventDispatcher",
			"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
			"type": "->",
			"function": "callListeners",
			"file": "\/srv\/app\/vendor\/symfony\/event-dispatcher\/EventDispatcher.php",
			"line": 59,
			"args": [
				[
					"array",
					[
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						],
						[
							"object",
							"Closure"
						]
					]
				],
				[
					"string",
					"kernel.request"
				],
				[
					"object",
					"Symfony\\Component\\HttpKernel\\Event\\RequestEvent"
				]
			]
		},
		{
			"namespace": "Symfony\\Component\\EventDispatcher",
			"short_class": "EventDispatcher",
			"class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
			"type": "->",
			"function": "dispatch",
			"file": "\/srv\/app\/vendor\/symfony\/http-kernel\/HttpKernel.php",
			"line": 129,
			"args": [
				[
					"object",
					"Symfony\\Component\\HttpKernel\\Event\\RequestEvent"
				],
				[
					"string",
					"kernel.request"
				]
			]
		},
		{
			"namespace": "Symfony\\Component\\HttpKernel",
			"short_class": "HttpKernel",
			"class": "Symfony\\Component\\HttpKernel\\HttpKernel",
			"type": "->",
			"function": "handleRaw",
			"file": "\/srv\/app\/vendor\/symfony\/http-kernel\/HttpKernel.php",
			"line": 75,
			"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\/app\/vendor\/symfony\/http-kernel\/Kernel.php",
			"line": 202,
			"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\/app\/vendor\/symfony\/runtime\/Runner\/Symfony\/HttpKernelRunner.php",
			"line": 35,
			"args": [
				[
					"object",
					"Symfony\\Component\\HttpFoundation\\Request"
				]
			]
		},
		{
			"namespace": "Symfony\\Component\\Runtime\\Runner\\Symfony",
			"short_class": "HttpKernelRunner",
			"class": "Symfony\\Component\\Runtime\\Runner\\Symfony\\HttpKernelRunner",
			"type": "->",
			"function": "run",
			"file": "\/srv\/app\/vendor\/autoload_runtime.php",
			"line": 29,
			"args": []
		},
		{
			"namespace": "",
			"short_class": "",
			"class": "",
			"type": "",
			"function": "require_once",
			"file": "\/srv\/app\/public\/index.php",
			"line": 5,
			"args": [
				[
					"string",
					"\/srv\/app\/vendor\/autoload_runtime.php"
				]
			]
		}
	]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions