Symfony/Doctrine Serializowanie kolekcji do Json

0

Odświeżam sobie trochę Symfony i robię taki mały projekcik. Chciałbym zapisywać sobie kolekcję ValueObject do bazy w formacie JSON.
Jeden ze sposobów jaki mi przyszedł do głowy to użycie Custom Types, ale przypuszczam, że to nie jest potrzebne.

Moje Entity wygląda tak:

class App
{
    public function __construct(
        private AppId $id,
        private string $name,
        private UserRoleCollection $userRoles
    ) {
    }
...
}

Mapowanie w xml

<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="https://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
                  xsi:schemaLocation="https://doctrine-project.org/schemas/orm/doctrine-mapping
                          https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">

    <entity name="App\Domain\App" table="app">
        <id name="id" column="id" type="AppId" />
        <field name="name" length="40" />
        <field name="userRoles" type="json" column="user_roles"/>
    </entity>

</doctrine-mapping>

Problematyczny obiekt UserRoleCollection wygląda tak:

<?php

declare(strict_types=1);

namespace App\Domain\ValueObject;

use ArrayIterator;
use Assert\Assertion;
use IteratorAggregate;
use JsonSerializable;
use Traversable;

final class UserRoleCollection implements IteratorAggregate, JsonSerializable
{
    private array $items;

    /**
     * @param UserRole[] $items
     */
    public function __construct(array $items = [])
    {
        Assertion::allIsInstanceOf($items, UserRole::class);
        $this->items = [];
        foreach ($items as $item) {
            $this->addItem($item);
        }
    }

    public function items(): array
    {
        return $this->items;
    }

(...)

    public function jsonSerialize()
    {
        return $this->items;
    }
}

Z UserRoleCollection chciałbym dojść do takiego stanu aby działało to jak z mapowanie typu "object" czyli pełen automat przy zapisie i odczycie z bazy, z tą różnicą że chcę w bazie mieć JSON a nie obiekt serializowany przez PHP. UserRolesCollection to kolekcja obiektów UserRole - po dodaniu interfejsu \JsonSerializable zapis już działa, ale niestety nie działa wczytanie obiektu z bazy. Problem polega na tym, że "items" to tablica obiektów i doctrine przy deserializacji próbuje wrzucić do niej zwykłe wartości tekstowe.

Pytanie więc czy jakoś w Symfony mogę Doctrine zmusić do serializowanie/deserializowania mojego obiektu np. przy użyciu JMS Serializer (albo jest jakiś inny sprytny sposób), czy też dla każdej takie kolekcji muszę rejestrować Custom Type i tam ręcznie wywoływać JMS Serializer?

0

A jakbyś stworzył jakiś customowy normalizer?

0

@serek: Wydaje mi się (ale mogę się mylić), że ta serializacja nie jest ogarniana Symfony, tylko to jest wbudowana funkcja Doctrine. Żeby użyć serializatora Symfony chyba i tak musiałbym stworzyć najpierw Custom Type i dopiero tam operować Serializatorem - w tym przypadku mogę po prostu użyć JMS Serializer. Chciałbym jednak uniknąć używania Custom Types w takich przypadkach. Chyba, ze się mylę i Symfony jednak wstrzykuje do Doctrine swój serializator (teraz nie mam jak sprawdzić)?

0

Szczerze nie bawiłem się nigdy w taki sposób z serializacją. U mnie po prostu ograniczało się to do zapisu array <=> json, więc u mnie to tylko takie gdybanie teraz.

0

Ja właśnie też do tej pory nie bawiłem się z serializacją w DB, ale teraz pod wpływem doświadczeń z NoSql i możliwościach jakie daje Postgres widzę całkiem fajne możliwości w zapisywaniu Value Objectów i kolekcji ValueObjectów w bazie.
Przykładowo jak masz np. opis i tłumaczenia to możesz wszystko trzymać w jednej tabeli. Jak masz np. encję Adres to możesz ją łatwo zapisać w 1 polu a nie 10 i jak coś tam dokładasz np. opcjonalny telefon, to nie musisz zmieniać struktury bazy. Ogólnie jest to w wielu miejscach ciekawe. Doctrine pozwala takie dane fajnie mapować, więc łatwo też oddzielić logikę domenową od persystencji.

0

Zobacz na symfonowego serializera: https://symfony.com/doc/current/components/serializer.html

1 użytkowników online, w tym zalogowanych: 0, gości: 1