获取实体所有子资源的自定义路径

custom path to get all the subressource of an entity

我是 Api-platform 2.6 的新手,我有点成功地完成了我尝试的事情,但我不知道这是不是“正确”或最简单的方法。

这是我正在尝试做的事情:

我得到了一个 esirius_site 实体,其中包含访问者集合。

访问者未存储在数据库中,而是从 api 端点获取。

我想要一条像这样的路线:/esirius_sites/{idsys}/visitors 那 return 一组访客(见下面的结果)。我不想要通往 return a esirius_site

的路线

我通过将访问者设置为子资源成功地做到了:

<?php

/**
 * @ORM\Entity(repositoryClass=EsiriusSiteRepository::class)
 * @ApiResource(
 *     collectionOperations={
 *     },
 *     itemOperations={
 *              "get",
 *
 *          }
 *     )
 */
class EsiriusSite
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     */
    private $idsys;

   /** Other properties... **/

    /**
     * @ApiSubresource()
     */
    private $visitors;

    public function __construct()
    {
        $this->visitors = [];
    }


    public function getIdsys(): ?int
    {
        return $this->idsys;
    }
  
    /**
     * @return array
     */
    public function getVisitors():array
    {
        return $this->visitors;
    }

    public function addVisitor(Visitor $visitor): self
    {
        $this->visitors[]=$visitor;
        $visitor->setEsiriusSite($this);
        return $this;
    }
}

然后我创建了一个数据提供程序来获取访问者集合:

<?php

namespace App\DataProvider;

class VisitorItemDataProvider implements SubresourceDataProviderInterface,RestrictedDataProviderInterface
{
    private EsiriusVisitorWebService $visitorWebService;
    private EsiriusSiteRepository $siteRepository;

    public function __construct(EsiriusVisitorWebService $visitorWebService, EsiriusSiteRepository $siteRepository)
    {
        $this->visitorWebService = $visitorWebService;
        $this->siteRepository = $siteRepository;
    }

    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
    {
        return $resourceClass === Visitor::class;
    }


    public function getSubresource(string $resourceClass, array $identifiers, array $context, string $operationName = null)
    {
        $site = $this->siteRepository->find($identifiers["idsys"]["idsys"]);
        $esiriusVisitors = ($this->visitorWebService->getVisitors([$site->getCode()]))->visitorArray;
        if($esiriusVisitors== new \stdClass())
            return [];

        foreach ($esiriusVisitors as $visitor) {
            $newVisitor = (new Visitor())->setFirstName($visitor->firstName)->setLastname($visitor->name)->setId($visitor->businessIdentity);
            $site->addVisitor($newVisitor);
        }
        return $site->getVisitors();
    }
}

在这个数据提供者中,我使用 SubresourceDataProviderInterface(我随机发现的)api 平台文档中没有提到。

我终于得到了我期待的结果:

{
    "@context": "/q0met-api/contexts/Visitor",
    "@id": "/q0met-api/esirius_sites/18/visitors",
    "@type": "hydra:Collection",
    "hydra:member": [
        {
            "@id": "/q0met-api/visitors/1234",
            "@type": "Visitor",
            "id": "1234",
            "firstName": "Jean",
            "lastname": "Michel",
            "esiriusSite": "/q0met-api/esirius_sites/18"
        }
    ],
    "hydra:totalItems": 1
}

我做得对吗?有没有更好的方法可以不使用这个未记录的界面?

@soyuka 证实,我的解决方案很好