2016-12-16 31 views
9

Here Buduję pakiet SDK Symfony dla REST API. Większość danych to obiekty JSON z zagnieżdżonymi innymi obiektami JSON. Jak tutajDenormalizacja denormalizowanych denormalizatorów Symfony 2

{ 
    "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" 
      } 
     } 
    } 
} 

Deserializacji musi produkować obiekt równą obiektowo produkowane przez kod podany poniżej:

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

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

$tournament->setCoverage($coverage); 

używam moje własne niestandardowe Denormalizers, poniżej fragment kodu denormalizer dla obiektów Tournament :

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; 
    } 
} 

Pytanie, w jaki sposób należy uzyskać dostęp do TerritoryDenormalizer wewnątrz programu TournamentDenormalizer? Widzę dwie opcje:

Pierwszy (używam teraz) jest dodanie implements DenormalizerAwareInterface do podpisania klasy denormalizer i polegać na Symfony\Component\Serializer\Serializer Klasa:

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

Więc w TournamentDeserializer będzie to jak tutaj :

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

drugie podejście Czy wstrzyknąć niezbędne denormalizers się wyraźnie

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

Więc w TournamentDeserializer będzie to jak tutaj:

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

Która z metod jest najlepsza? Jakie alternatywne podejścia są możliwe?

Odpowiedz

1

Wprowadzenie urządzenia do normalizacji NormalizerAwareInterface (i ostatecznie użycie) jest sposobem na przejście, interfejs ten został wprowadzony dla tego konkretnego przypadku użycia.