-1

I'm new with Api-platform 2.6 and i kind of succeeded to do what i attempted but i don't know if it's the "right" or easiest way to do it.

Here's what i'm trying to do:

i got an esirius_site entity that that have a collection of visitors.

The visitors are not stored in the database but they are fetched from an api endpoint.

I want to have a route like : /esirius_sites/{idsys}/visitors that return a collection of visitors (see result bellow). I don't want the route to return a esirius_site

i succeeded to do it by setting the visitors as a sub-resource:

<?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;
    }
}

and then i created a Data provider to fetch the visitor collection :

<?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();
    }
}

In this data provider i use the SubresourceDataProviderInterface (i found it randomly) that's not mentioned in the api platform documentation.

I finally got the result that i espect:

{
    "@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
}

Am i doing right ? is there a better way to do it maybe without using this not documented interface ?

Floxblah
  • 152
  • 9
  • 1
    This is correct good job! – soyuka Aug 18 '21 at 14:02
  • @soyuka i saw you also answer to my comment about this interface [in github](https://github.com/api-platform/docs/pull/446#issuecomment-901141353). But in your reply you said that this interface will be deprecated and then removed... So my implementation will not work in the future. There is no other way to implement what i'm trying to do ? – Floxblah Aug 18 '21 at 15:07
  • 1
    don't worry there'll be a way to still use your code and instructions on how to update – soyuka Aug 19 '21 at 09:39

1 Answers1

0

as @soyuka confirm, my solution is good

Floxblah
  • 152
  • 9