1

I'm using Symfony Serializer with FOSRestBundle. So the problems are:

  • it uses snake_case by default
  • I can't set setCircularReferenceHandler callback. I set in services.yml, but the property is equal to null when debugging. And server throws CircularReferenceException.

My config.yml:

framework:
    serializer: { enable_annotations: true }
#.....
fos_rest:
    param_fetcher_listener: true
    body_listener: true
    format_listener:
        rules:
            - { path: '^/oauth', priorities: ['json'], fallback_format: json, prefer_extension: false }
            - { path: '^/api', priorities: ['json'], fallback_format: json, prefer_extension: false }
            - { path: '^/', stop: true }
    view:
        view_response_listener: true
    access_denied_listener:
        json: true
    exception:
        enabled: true
    serializer:
        serialize_null: true

My services.yml:

circular_reference_handler:
    public: false
    class: callback
    factory: [ApiBundle\Serializer\CircularHandlerFactory, getId]

serializer.normalizer.get_set_method:
    class: ApiBundle\Serializer\Normalizer\GetSetMethodNormalizer
    public: false
    tags: [serializer.normalizer]
    calls:
        - method: setCircularReferenceLimit
          arguments: [1]
        - method: setCircularReferenceHandler
          arguments: ['@circular_reference_handler']

Normalizer:

class GetSetMethodNormalizer extends BaseGetSetMethodNormalizer
{
    /**
     * {@inheritdoc}
     */
    public function supportsNormalization($data, $format = null)
    {
        return !$data instanceof \Exception && parent::supportsNormalization($data, $format);
    }
}

CircularHandler:

class CircularHandlerFactory
{
    /**
     * @return \Closure
     */
    public static function getId()
    {
        return function ($object) {
            return $object->getId();
        };
    }
}

Entity:

class PartnerGuaranteeImportArchive
{
    use IdentityBehavior;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=255, unique=true)
     */
    private $fileName;

    /**
     * @var string
     *
     * @Serializer\Groups({"partnerGuaranteeImportArchive"})
     *
     * @ORM\Column(type="string", length=255)
     */
    private $originalFileName;

    /**
     * @var string
     *
     * @Serializer\Groups({"partnerGuaranteeImportArchive"})
     *
     * @ORM\Column(type="string", length=20)
     */
    private $importStatus;

    /**
     * @var \DateTime
     *
     * @Serializer\Groups({"partnerGuaranteeImportArchive"})
     *
     * @Gedmo\Timestampable(on="create")
     *
     * @ORM\Column(type="datetime")
     */
    private $createdAt;

    /**
     * @var \DateTime
     *
     * @Serializer\Groups({"partnerGuaranteeImportArchive"})
     *
     * @Gedmo\Timestampable(on="update")
     *
     * @ORM\Column(type="datetime")
     */
    private $updatedAt;

    /**
     * @var string
     *
     * @Serializer\Groups({"partnerGuaranteeImportArchive"})
     *
     * @ORM\Column(type="text", nullable=true)
     */
    private $errorMessage;

    /**
     * @var int
     *
     * @Serializer\Groups({"partnerGuaranteeImportArchive"})
     *
     * @ORM\Column(type="integer", options={"default": 0})
     */
    private $rows = 0;

    /**
     * @var null
     *
     * @Serializer\Groups({"partnerGuaranteeImportArchive"})
     *
     * @ORM\Column(type="integer", nullable=true)
     */
    private $errorCode = null;

    /**
     * @var PartnerOcamUser
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\PartnerOcamUser", inversedBy="partnerGuaranteeImportArchives")
     * @ORM\JoinColumn(name="partner_ocam_user_id", referencedColumnName="id")
     */
    private $partnerOcamUser;

    // ....
}

Controller action:

/**
 * @Rest\Get(name="api_v1_import_partner_guarantee_archive_index")
 * @Rest\View(statusCode=200, serializerGroups={"partnerGuaranteeImportArchive"})
 *
 * @param Request $request
 * @param PaginationFactory $paginationFactory
 * @return array
 */
public function indexAction(Request $request, PaginationFactory $paginationFactory)
{
    $qb = $this->getDoctrine()->getRepository('AppBundle:PartnerGuaranteeImportArchive')
        ->getByPartnerOcamUser($this->getUser());

    return $paginationFactory
        ->setMaxPage(self::PAGE_COUNT)
        ->createCollection($qb, $request, 'api_v1_import_partner_guarantee_archive_index')
        ->toArray();
}

2 Answers 2

2

I've been searching for a long time how to use Symfony Serializer with FOSRestBundle. All tutorials are about JMS Serializer. After searching a while I decided to use custom Symfony Normalizer:

<?php

namespace ApiBundle\Serializer\Normalizer;

use AppBundle\Entity\PartnerInsuredImportArchive;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class PartnerInsuredImportArchiveNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
    use NormalizerAwareTrait;

    /**
     * @param PartnerInsuredImportArchive $object
     * @param string|null $format
     * @param array $context
     * @return array
     */
    public function normalize($object, $format = null, array $context = [])
    {
        return [
            'id' => $object->getId(),
            'originalFileName' => $object->getOriginalFileName(),
            'importStatus' => $object->getImportStatus(),
            'rows' => $object->getRows(),
            'errorCode' => $object->getErrorCode(),
            'errorMessage' => $object->getErrorMessage(),
            'createdAt' => $this->normalizer->normalize($object->getCreatedAt()),
            'updatedAt' => $this->normalizer->normalize($object->getUpdatedAt()),
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function supportsNormalization($data, $format = null)
    {
        return $data instanceof PartnerInsuredImportArchive;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

This is a bit old topic, but I managed to make this bundle work with Symfony Serializer as follows:

fos_rest.yaml:

fos_rest:
    service:
        serializer: fos_rest.serializer.symfony

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.