Skip to content

ObjectMapperOutputProcessor ignores operation output class #7940

@lordgretix

Description

@lordgretix

API Platform version(s) affected: 4.3.x

Description
The ObjectMapperOutputProcessor::process() class (in src/State/Processor/ObjectMapperOutputProcessor.php) during the conversion of the object back to DTO uses $operation->getClass() as target for the objectMapper. Therefore ignores the output argument defined in the operation.

Current ObjectMapperOutputProcessor::process():

    public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): object|array|null
    {
        if (
            $data instanceof Response
            || !$this->objectMapper
            || !($operation->canWrite() ?? true)
            || null === $data
            || !$operation->canMap()
        ) {
            return $this->decorated ? $this->decorated->process($data, $operation, $uriVariables, $context) : $data;
        }

        $request = $context['request'] ?? null;
        $request?->attributes->set('persisted_data', $data);
        $dto = $this->objectMapper->map($data, $operation->getClass());

        return $this->decorated ? $this->decorated->process($dto, $operation, $uriVariables, $context) : $dto;
    }

How to reproduce

This code should return a CustomOutput object with $anotherValue, instead it returns SomeResource

#[ApiResource(
    shortName: 'SomeResource',
    operations: [
        new Post(
            output: CustomOutput::class,
        )
    ],
)]
class SomeResource {

    public string $someValue;
    
    public string $anotherValue;
    
}

class CustomOutput {
    
    public string $anotherValue;
}

Possible Solution

Taking a peek at ObjectMapperInputProcessor::process() (in src/State/Processor/ObjectMapperInputProcessor.php). The output class could be determined in the same way:

$class = $operation->getInput()['class'] ?? $operation->getClass();

So in the output proccesor it should be:

$class = $operation->getOutput()['class'] ?? $operation->getClass();

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions