带有 FOSRestBundle 的 Symfony 序列化程序?
Symfony Serializer with FOSRestBundle?
我正在使用带有 FOSRestBundle 的 Symfony 序列化器。
所以问题是:
- 默认使用snake_case
- 我无法设置 setCircularReferenceHandler 回调。我设置了
services.yml,但调试时属性等于null。和
服务器抛出 CircularReferenceException。
我的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;
}
}
我正在使用带有 FOSRestBundle 的 Symfony 序列化器。 所以问题是:
- 默认使用snake_case
- 我无法设置 setCircularReferenceHandler 回调。我设置了 services.yml,但调试时属性等于null。和 服务器抛出 CircularReferenceException。
我的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;
}
}