guns17
guns17

Reputation: 155

deserialize json to array of entities

I would like to deserialize a JSON to an object having an entity relation.

incoming JSON data


    {
          "name": "john",
          "books": [
            {
              "title": "My life"
            }
          ]
    }

The result of json deserialization like this

$object = $this->get('serializer')->deserialize($jsonData, 'Author', 'json');

is

 Author { #name: 'john' #books: array:1 [ 0 => array:1 [ "title" => "My life" ] ] }

I would like to deserialize to an object like this

Author { #name: 'john' #books: array:1 [ Book { "title" => "My life" } ] }

I understand why deserialization is not able to deserialize Book. With JMSSerialzerBundle, the Type annotation exists to resolve that case.

Is it possible to do it with the Symfony Serializer component or must i use the JMSSerializer for that ?

Thanks for your help ;)

My objects


class Author

    {
        private $name;

        private $books;

        /**
         * @return mixed
         */
        public function getName()
        {
            return $this->name;
        }

        /**
         * @param mixed $name
         */
        public function setName($name)
        {
            $this->name = $name;
        }

        /**
         * @return mixed
         */
        public function getBooks()
        {
            return $this->books;
        }

        /**
         * @param mixed $books
         */
        public function setBooks(array $books)
        {
            $this->books = $books;
        }
    }

    class Book
    {
        private $title;

        private $author;

        /**
         * @return mixed
         */
        public function getTitle()
        {
            return $this->title;
        }

        /**
         * @param mixed $title
         */
        public function setTitle($title)
        {
            $this->title = $title;
        }

        /**
         * @return mixed
         */
        public function getAuthor()
        {
            return $this->author;
        }

        /**
         * @param mixed $author
         */
        public function setAuthor(Author $author)
        {
            $this->author = $author;
        }
    }

Upvotes: 2

Views: 3159

Answers (2)

Kévin Dunglas
Kévin Dunglas

Reputation: 3024

Guilhem is right, the default Symfony ObjectNormalizer isn't able to normalize properties of non scalar types for now.

However, this feature is being added in Symfony 3.1: https://github.com/symfony/symfony/pull/17660

In the meantime, you can copy/paste the ObjectNormalizer version provided in the PR linked above in your project.

You can also take a look at a similar implementation available in API Platform:

Upvotes: 1

Guilhem N
Guilhem N

Reputation: 218

The symfony serializer can't denormalize complex properties.

I think that the only way to do that is to manage your object denormalization by yourself:

use Symfony\Component\Serializer\Normalizer\DenormalizableInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

class Author implements DenormalizableInterface {
    public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array()) {
        if (isset($data['name'])) {
            $this->setName($data['name']);
        }
        if (isset($data['books']) && is_array($data['books'])) {
            $books = array();
            foreach ($data['books'] as $book) {
                $books[] = $denormalizer->denormalize($book, Book::class, $format, $context);
            }
            $this->setBooks($books);
        }
    }

    // ...
}

You can also create a custom normalizer but this is more complicated (you can take a look at this article which explains more or less how to do that).

I hope this will help you :-)

Upvotes: 1

Related Questions