Symfony 2 денормализация вложенных объектов с помощью пользовательских денормализаторов

Вот Я создаю Symfony SDK для REST API. Большинство данных являются объектами JSON с вложенными другими объектами JSON. Как здесь

{
"id": "eng_pl",
"name": "Premier League",
"_links": {
"self": {
"href": "/tournaments/eng_pl"},
"seasons": {
"href": "/tournaments/eng_pl/seasons/"}
},
"coverage": {
"id": "eng",
"name": "England",
"_links": {
"self": {
"href": "/territories/eng"}
}
}
}

Десериализация должна производить объект, равный объекту, произведенному кодом, перечисленным ниже:

$tournament = new Tournament();
$tournament->setId('eng_pl');
$tournament->setName('Premier League');

$coverage = new Territory();
$coverage->setId('eng');
$coverage->setName('England');

$tournament->setCoverage($coverage);

Я использую свои собственные денормализаторы ниже фрагмента кода денормализатора для объектов Турнира:

class TournamentDenormalizer implements DenormalizerInterface
{

/**
* @inheritdoc
*/
public function supportsDenormalization($object, $type, $format = null)
{

if ($type != Tournament::class) {
return false;
}
return true;
}

/**
* @inheritdoc
* @return Tournament
*/
public function denormalize($object, $class, $format = null, array $context = array())
{
$tournament = new Tournament();
$tournament->setId($object->id);
$tournament->setName($object->name);

if (isset($object->coverage)) {
/** @var Territory $coverage */
$coverage = ???; //HOWTO how to implement Territory denormalization here???
$tournament->setCoverage(
$coverage
);
}
return $tournament;
}
}

Вопрос в том, как получить доступ к TerritoryDenormalizer внутри TournamentDenormalizer? Я вижу два варианта:

Первый (Сейчас пользуюсь) стоит добавить implements DenormalizerAwareInterface подписи класса денормализатора и положиться на Symfony\Component\Serializer\Serializer учебный класс:

$serializer = new Symfony\Component\Serializer\Serializer(
[
new TournamentDenormalizer(),
new TerritoryDenormalizer()
], [
new Symfony\Component\Serializer\Encoder\JsonDecode()
]
);
$serializer->deserialize($json, Tournament::class, 'json');

Так в TournamentDeserializer это будет как здесь:

if (isset($object->coverage)) {
/** @var Territory $coverage */
$coverage = $this->denormalizer->denormalize(
$object->coverage,
Territory::class,
$format,
$context
);
$tournament->setCoverage(
$coverage
);
}
}

Второй подход
Явно вводить необходимые денормализаторы

$tournamentDenormalizer = new TournamentDenormalizer();
$tournamentDenormalizer->setTerritoryDenormalizer(new TerritoryDenormalizer());

Так в TournamentDeserializer это будет как здесь:

if (isset($object->coverage)) {
/** @var Territory $coverage */
$coverage = $this->territoryDenormalizer->denormalize(
$object->coverage,
Territory::class,
$format,
$context
);
$tournament->setCoverage(
$coverage
);
}
}

Какой из подходов является лучшим? Какие альтернативные подходы возможны?

12

Решение

Заставить ваш нормализатор реализовать NormalizerAwareInterface (и в конечном итоге использовать NormalizerAwareTrait) это путь, этот интерфейс был введен для этого конкретного случая использования.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]