带有 FOSRestBundle 的 Symfony 序列化程序?

Symfony Serializer with FOSRestBundle?

我正在使用带有 FOSRestBundle 的 Symfony 序列化器。 所以问题是:

我的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

我的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']

标准化器:

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

循环处理器:

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

实体:

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;

    // ....
}

控制器动作:

/**
 * @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();
}

我一直在寻找如何将 Symfony Serializer 与 FOSRestBundle 一起使用。所有教程都是关于 JMS Serializer 的。搜索了一段时间后,我决定使用自定义 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;
    }
}