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



我是api平台2.6的新手,我成功地做了我尝试过的事情,但我不知道它是否"正确"。或者是最简单的方法。

这就是我要做的:

我得到了一个esirius_site实体,它有一个访问者集合。

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

我想有一个像:/esirius_sites/{idsys}/visitors这样的路由,它返回访问者的集合(见下面的结果)。我不希望路由返回一个esirius_site

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

<?php
/**
* @ORMEntity(repositoryClass=EsiriusSiteRepository::class)
* @ApiResource(
*     collectionOperations={
*     },
*     itemOperations={
*              "get",
*
*          }
*     )
*/
class EsiriusSite
{
/**
* @ORMId
* @ORMColumn(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 AppDataProvider;
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();
}
}

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

我终于得到了我想要的结果:

{
"@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确认,我的解决方案是好的

最新更新