Symfony: Рекурсивная денормализация не поддерживает object_to_populate.

Созданный на 18 февр. 2017  ·  3Комментарии  ·  Источник: symfony/symfony

| Вопрос | А
| ---------------- | -----
| Сообщение об ошибке? | нет
| Запрос функции? | да
| Отчет о перерыве в БК? | нет
| RFC? | нет
| Версия Symfony | 3.3.0

Было бы очень полезно, если бы существовал способ рекурсивной десериализации объектов.

Учитывая такой объект:

class User
{

    /**
     * Set Name.
     *
     * <strong i="15">@param</strong> Name $name
     */
    public function setName(Name $name) : self
    {
        $this->name = $name;

        return $this;
    }
}

Сериализатор выдает Symfony\Component\Serializer\Exception\UnexpectedValueException с сообщением «Ожидаемый аргумент типа ‘Имя’, ‘массив’ указан», потому что он передает массив в setName() , а не выполняет денормилизацию на Name класс, а затем передать результат в setName() . Я мог бы, конечно, разрешить этому методу принимать имя и массив, но тогда он пропустит:
1) Заполнение существующего объекта имени
2) Любые группы, которые могут быть использованы для доступа.

Поскольку у метода уже есть подсказка типа единственного, что он примет (класс), я думаю, имеет смысл, если в сеттере встречается подсказка нескалярного типа, он должен:
1) Запустите денормализатор с классом подсказки типа в качестве типа.
2) Передать те же группы от родителя к ребенку
3) Попытка получить значение свойства, если значение возвращается, оно должно использовать это значение в object_to_populate (при условии, что object_to_populate было установлено для родителя)

Feature Serializer

Самый полезный комментарий

Ну, это было не сразу очевидно, но я нашел это:
https://github.com/symfony/symfony/blob/3.2/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml#L25

что привело меня к установке компонента ProperyInfo и включению его в моем config.yml :

framework:
    property_info:
        enabled: true

Это _в основном_ решает мои проблемы. Он поддерживает рекурсию и группы, однако не поддерживает object_to_populate . Я собираюсь изменить этот вопрос, чтобы он касался этого, а не самой рекурсии, которую Symfony явно поддерживает (хотя и плохо документирован).

Все 3 Комментарий

Ну, это было не сразу очевидно, но я нашел это:
https://github.com/symfony/symfony/blob/3.2/src/Symfony/Bundle/FrameworkBundle/Resources/config/serializer.xml#L25

что привело меня к установке компонента ProperyInfo и включению его в моем config.yml :

framework:
    property_info:
        enabled: true

Это _в основном_ решает мои проблемы. Он поддерживает рекурсию и группы, однако не поддерживает object_to_populate . Я собираюсь изменить этот вопрос, чтобы он касался этого, а не самой рекурсии, которую Symfony явно поддерживает (хотя и плохо документирован).

В документации отсутствует информация о том, как вам нужно активировать PropertyInfo, чтобы десериализовать встроенный объект, я уже писал об этом: https://github.com/symfony/symfony-docs/issues/7387

Что касается третьей проблемы (теперь только проблемы), object_to_populate используется для обновления/использования уже существующего объекта вместо создания нового. Вы говорите, что если родитель использует эту опцию, встроенные объекты также должны ее использовать. Я вижу необходимость использовать существующий объект в качестве значения свойства, но:

  1. Использование существующего объекта не означает, что все свойства, являющиеся объектами, являются «объектами для заполнения» (уже существующими объектами). Иногда вам может потребоваться создать объекты для добавления к родительскому, поэтому расширение «object_to_populate» на все свойства по умолчанию не является допустимым вариантом.
  2. Итак, вам нужен способ определить, какие свойства являются «объектами для заполнения» и как получить доступ к уже существующим объектам, и у вас нет уникального и универсального способа сделать это, потому что это значение можно получить из базы данных. , из ресурса API, даже из какой-нибудь хэш-карты в памяти. Например, в проекте API Platform они используют разыменовываемые IRI для идентификации встроенных отношений: https://api-platform.com/docs/core/serialization-groups-and-relations#embedding-relations . И даже в этом случае используется только для связи одного существующего объекта с другим, а не для изменения/обновления внедренного объекта.

Комментарий @davidbarratt помог мне понять, что мне нужно установить PropertyInfoComponent и добавить конфигурацию framework.property_info.enabled , чтобы сериализатор мог десериализовать объекты со свойствами \DateTime . Это не обязательно для сериализации, и я не смог найти ничего в документе, где это упоминается.
Без этого сериализация объекта со свойством \DateTime работает, но его десериализация сразу после этого терпит неудачу. Это (сериализация _и десериализация_ объектов со свойствами \DateTime ) кажется вероятным сценарием, поэтому я бы предложил упомянуть об этом в документации, чтобы избавить других разработчиков от разочарования и лихорадочного гугления.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги