与this question类似,我使用的是带有Doctrine实体的API平台--我有一个包含值的实体:
/**
* @ApiResource()
*/
class Credit
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="integer")
*/
private $value;
}我想检索这个值的和,并在查询集合时在响应的顶层元素中返回它:
{
"@context": "/api/contexts/Credit",
"@id": "/api/credits",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/credits/1",
"@type": "Credit",
"id": 1,
"value": 200,
"createdAt": "2019-03"
},
{
"@id": "/api/credits/2",
"@type": "Credit",
"id": 2,
"value": 200,
"createdAt": "2019-04"
}
],
"hydra:totalItems": 2,
"totalValues": 400
}但是,我希望使用查询的副本来实现这一点,而不是在执行之后对值进行求和,以便在应用分页时保持相同的totalValues数量--这与hydra:totalItems总是返回总项数的方式非常相似。
实现这一目标的最佳途径是什么?
发布于 2022-08-11 14:04:23
您可以创建一个CreditCollectionNormalizer
<?php
namespace App\Serializer\Normalizer;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
class CreditCollectionNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
public const RESOURCE_CLASS = \App\Entity\Credit::class;
private const ALREADY_CALLED = 'CREDIT_COLLECTION_NORMALIZER_ALREADY_CALLED';
private NormalizerInterface $normalizer;
public function __construct(NormalizerInterface $normalizer)
{
$this->normalizer = $normalizer;
}
public function normalize($object, string $format = null, array $context = []): array
{
$context[self::ALREADY_CALLED] = true;
$data = $this->normalizer->normalize($object, $format, $context);
if ('collection' === $context['operation_type'] &&
'get' === $context['collection_operation_name'] &&
self::RESOURCE_CLASS == $context['resource_class']) {
$balance = 0;
foreach ($object as $item) {
$balance += $item->amount;
}
$data['hydra:meta']['balance'] = $balance;
}
return $data;
}
public function supportsNormalization($data, string $format = null, array $context = []): bool
{
return $this->normalizer->supportsNormalization($data, $format, $context);
}
public function setNormalizer(NormalizerInterface $normalizer)
{
if ($this->normalizer instanceof NormalizerAwareInterface) {
$this->normalizer->setNormalizer($normalizer);
}
}
}然后将其注册为CollectionNormalizer装饰器在services.yaml中
services:
App\Serializer\Normalizer\CreditCollectionNormalizer:
decorates: 'api_platform.hydra.normalizer.collection'
arguments: [ '@App\Serializer\Normalizer\CreditCollectionNormalizer.inner' ]
public: falseapi/credits现在应该返回以下内容:
{
"@context": "/api/contexts/Credit",
"@id": "/api/credits",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/api/credits/1",
"@type": "Credit",
"id": 1,
"value": 200,
"createdAt": "2019-03"
},
{
"@id": "/api/credits/2",
"@type": "Credit",
"id": 2,
"value": 200,
"createdAt": "2019-04"
}
],
"hydra:totalItems": 2,
"hydra:meta": {
"balance": 400
}
}https://stackoverflow.com/questions/62831601
复制相似问题