如何在 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' ]