Serializing entiy with property referencing an entity of the same type?

Viewed 121

I have an entity that has a property that points to another object of the same type, like duplicatedFrom for an entity that's marked as a duplicate of an existing entity.

The entity class is something like this:

class Foo
{
    private string $id;
    private string $name;
    private string $content;
    private ?Foo duplicatedFrom;
}

I would like the returned result to be something like:

{
   "@id": "/api/foo/2",
   "@type": "Foo",
   "name": "bar",
   "content": "abce",
   "duplicatedFrom": "/api/foo/1"
}

But instead I get:

{
   "@id": "/api/foo/2",
   "@type": "Foo",
   "name": "bar",
   "content": "abce",
   "duplicatedFrom": {
      "@id": "/api/foo/1",
      "@type": "Foo",
      "name": "bar",
      "content": "abce",
      "duplicatedFrom": null
   }
}

The entity reference by Foo::duplicatedFrom is fully serialized, where I would like to ahve it only with the id value, not with the whole entity.

I've been playing with the serializer configuration, setting the max-depth for duplicatedFrom to either 0 or 1, but the results are the same.

The serializer group that applies:

<serializer xmlns="http://symfony.com/schema/dic/serializer-mapping">
    <class name="Foo">
        <!-- rest of the declaration omitted -->
        <!-- tried with max-depth 1 and 0 -->
        <attribute name="duplicatedFrom" max-depth="1">
            <group>foo_item</group>
            <group>foo_collection</group>
       </attribute>
  </class>
</serializer>

The api resource configuration:

<resources xmlns="https://api-platform.com/schema/metadata">
    <resource class="Foo">
    <attribute name="normalization_context">
       <attribute name="groups">
            <attribute>foo_collection</attribute>
       </attribute>
    </attribute>
</resource>

How can I accomplish this?

1 Answers

I can't understand why this can't be accomplished with an annotation. You can make another getter with needed group, instead binding group to the exact property.

For your example:

/**
 * @Groups({"foo"})
 */
private ?Foo duplicatedFrom;

You could do something like:

private ?Foo duplicatedFrom;

/**
 * @Groups({"foo"})
 */
 public function getDuplicatedFromId(): ?string
 { 
    return $this->getDuplicatedFrom()->getId();
 }

I know thats it's not the best way, but it could be helpful.

Related