如何在 api-platform 结果上添加额外信息
How to add an extra information on api-platform result
我正在使用 symfony 和 api 平台。
我有一个资源:
/**
* @ApiResource()
*/
class Credit
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="integer")
*/
private $value;
}
/api/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
}
i want to add an extra information to my result like the totalValues :
400 ( sum of "value" of all results )
how can i do it
预期结果:
{
"@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
}
解决方案是像这样实现 NormalizerInterface 和 NormalizerAwareInterface :
ApiCollectionNormalizer:
namespace App\Serializer;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
final class ApiCollectionNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
/**
* @var NormalizerInterface|NormalizerAwareInterface
*/
private $decorated;
public function __construct(NormalizerInterface $decorated)
{
if (!$decorated instanceof NormalizerAwareInterface) {
throw new \InvalidArgumentException(
sprintf('The decorated normalizer must implement the %s.', NormalizerAwareInterface::class)
);
}
$this->decorated = $decorated;
}
/**
* @inheritdoc
*/
public function normalize($object, $format = null, array $context = [])
{
$data = $this->decorated->normalize($object, $format, $context);
if ('collection' === $context['operation_type'] && 'get' === $context['collection_operation_name']) {
if ($data['@id'] === '/api/credits') {
$totalValues = 0;
foreach ($data['hydra:member'] as $credit) {
$totalValues += $credit['value'];
}
$data['totalValues'] = $totalValues;
}
}
return $data;
}
/**
* @inheritdoc
*/
public function supportsNormalization($data, $format = null)
{
return $this->decorated->supportsNormalization($data, $format);
}
/**
* @inheritdoc
*/
public function setNormalizer(NormalizerInterface $normalizer)
{
$this->decorated->setNormalizer($normalizer);
}
}
services.yaml :
'App\Serializer\ApiCollectionNormalizer':
decorates: 'api_platform.hydra.normalizer.collection'
arguments: [ '@App\Serializer\ApiCollectionNormalizer.inner' ]
我正在使用 symfony 和 api 平台。
我有一个资源:
/**
* @ApiResource()
*/
class Credit
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="integer")
*/
private $value;
}
/api/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
}
i want to add an extra information to my result like the totalValues : 400 ( sum of "value" of all results )
how can i do it
预期结果:
{
"@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
}
解决方案是像这样实现 NormalizerInterface 和 NormalizerAwareInterface :
ApiCollectionNormalizer:
namespace App\Serializer;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
final class ApiCollectionNormalizer implements NormalizerInterface, NormalizerAwareInterface
{
/**
* @var NormalizerInterface|NormalizerAwareInterface
*/
private $decorated;
public function __construct(NormalizerInterface $decorated)
{
if (!$decorated instanceof NormalizerAwareInterface) {
throw new \InvalidArgumentException(
sprintf('The decorated normalizer must implement the %s.', NormalizerAwareInterface::class)
);
}
$this->decorated = $decorated;
}
/**
* @inheritdoc
*/
public function normalize($object, $format = null, array $context = [])
{
$data = $this->decorated->normalize($object, $format, $context);
if ('collection' === $context['operation_type'] && 'get' === $context['collection_operation_name']) {
if ($data['@id'] === '/api/credits') {
$totalValues = 0;
foreach ($data['hydra:member'] as $credit) {
$totalValues += $credit['value'];
}
$data['totalValues'] = $totalValues;
}
}
return $data;
}
/**
* @inheritdoc
*/
public function supportsNormalization($data, $format = null)
{
return $this->decorated->supportsNormalization($data, $format);
}
/**
* @inheritdoc
*/
public function setNormalizer(NormalizerInterface $normalizer)
{
$this->decorated->setNormalizer($normalizer);
}
}
services.yaml :
'App\Serializer\ApiCollectionNormalizer':
decorates: 'api_platform.hydra.normalizer.collection'
arguments: [ '@App\Serializer\ApiCollectionNormalizer.inner' ]