Skip to content

[ES] Normalization \DateTimeImmutable throws MissingConstructorArgumentsException #3908

Description

@darthf1

API Platform version(s) affected: 2.5.8

Description
When using Elasticsearch, normalizing \DateTimeImmutable fields throws a MissingConstructorArgumentsException

How to reproduce
I have an entity with a \DateTimeImmutable field.

class MyEntity
{
    /**
     * @ORM\Column(type="datetime_immutable", nullable=true)
     */
    private ?\DateTimeImmutable $date = null;

    public function getDate(): ?\DateTimeImmutable
    {
        return $this->date;
    }

    public function setDate(?\DateTimeImmutable $date): self
    {
        $this->date = $date;

        return $this;
    }
}

I have an ES index setup for this entity, where I mapped this field to the date type.

fos_elastica:
  indexes:
    my_entity:  
      use_alias: true
      index_name: my_entity
      dynamic: strict
      properties:
        date:
          type: date

Populating via the FOSElasticaBundle works ok. When I fetch the data with a GET request, the following error is thrown:

Uncaught PHP Exception Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException: "Cannot create an instance of "DateTimeImmutable" from serialized data because its constructor requires parameter "time" to be present." at /srv/api/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php line 394

Additional Context
When I provide a datetime_format in the $defaultContext for the DateTimeNormalizer`, the normalization error disappears:

Symfony\Component\Serializer\Normalizer\DateTimeNormalizer:
  arguments:
    $defaultContext:
      datetime_format: 'Y-m-d H:i:s'

This however lead to a new error in my PHPUnit tests:

App\Tests\Functional\Entity\MyEntity::testPostItemRequest
Failed asserting that Array &0 (
    '@context' => '/api/contexts/MyEntity'
    '@id' => '/api/my_entity/0f0e11b6-dccd-4f3e-8318-0be53e87a5d6'
    '@type' => 'MyEntity'
    'date' => '2020-12-16 17:15:17'
) matches the provided JSON Schema.
date: Invalid date-time "2020-12-16 17:15:17", expected format YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm

Thrown by this line:

self::assertMatchesResourceItemJsonSchema(MyEntity::class);

Specifying the datetime_format in the ApiResource annotation has zero effect. Both the GET request as the PHPUnit test fail with the same error messages:

/**
 * @ApiResource(
 *     attributes={
 *         "normalization_context"={
 *             "datetime_format" = "Y-m-d H:i:s",
 *         },
 *     },
 * )
 **/
class MyEntity {}

What does work for both the GET request as the PHPUnit test is specifying the format in the DateTimeNormalizer service as RFC3339:

  Symfony\Component\Serializer\Normalizer\DateTimeNormalizer:
    arguments:
      $defaultContext:
        datetime_format: 'Y-m-d\TH:i:sP'

My preferable outcome would be to not having to touch anything at all; I'm perfectly fine with the default YYYY-MM-DDThh:mm:ssZ or YYYY-MM-DDThh:mm:ss+hh:mm format. I would expect defining a datetime_format in the normalization_context would have an impact.

Probably related to #3878

Metadata

Metadata

Assignees

No one assigned

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions