Skip to content

Required toString implementation for identifier VO in API resource #1414

@SpiGAndromeda

Description

@SpiGAndromeda

Today I wanted to change the identifier of an entity from an ordinary UUID to a name. Both the UUID and name are value objects. Their actual values are scalar private properties of the entities and the VOs are only an interface.

class Template
{
    private DateTimeImmutable $createdAt;
    private string $name;
    private array $variables;

    public function __construct(
        DateTimeImmutable $createdAt,
        Name $name,
        Variables $variables,
    ) {
        $this->setCreatedAt($createdAt);
        $this->name = $name->get();
        $this->setVariables($variables);
    }

    public function getCreatedAt(): DateTimeImmutable
    {
        return $this->createdAt;
    }

    public function getName(): Name
    {
        return new Name($this->name);
    }

    public function getVariables(): Variables
    {
        return Variables::new($this->variables);
    }

    public function setCreatedAt(DateTimeImmutable $createdAt): void
    {
        $this->createdAt = $createdAt;
    }

    public function setVariables(Variables $variables): void
    {
        $this->variables = $variables->toRawArray();
    }
}

The name VO looks like this:

final class Name
{
    public function __construct(private string $name)
    {
        if (empty($this->name)) {
            throw Blank::new('template name');
        }
    }

    public static function new(?string $name): ?self
    {
        return (null !== $name) ? new self($name) : null;
    }

    public function get(): string
    {
        return $this->name;
    }
}

After I removed the UUID and changed the doctrine id to the name, API Platform registered that quite well in it's OpenAPI doc. Unfortunatly the actual operations were not working as described here:
Stack Overflow Thread

The problem was, that I missed to add the __toString method to the name VO:

    public function __toString(): string
    {
        return $this->name;
    }

The documentation already has a section about custom identifiers: Identifiers. There is no information about the necessaty of the __toString method for this use case.

I am not quite sure where to put it and how to exlaint this use case. I guess not everybody uses VOs in this way. That's why I wanted to discuss that here. I will write an PR afterwards.

best regards,
spigandromeda

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