How apply serialization on custom GET collection operation
See original GitHub issueHi everyone!
I’m new user since few day on API Platform and i try to create a custom GET collection operation for a Station entity which has GPS coordonates attributes. The goal of the custom operation isn’t no to return all Stations but only return those in a certain distance. This is for the context.
So, my entity :
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
/**
* @ApiResource(attributes={"pagination_enabled"=false})
* @ORM\Entity(repositoryClass="App\Repository\StationRepository")
*/
class Station
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="float")
*/
private $latitude;
/**
* @ORM\Column(type="float")
*/
private $longitude;
public function getId(): ?int
{
return $this->id;
}
public function getLatitude(): ?float
{
return $this->latitude;
}
public function setLatitude(float $latitude): self
{
$this->latitude = $latitude;
return $this;
}
public function getLongitude(): ?float
{
return $this->longitude;
}
public function setLongitude(float $longitude): self
{
$this->longitude = $longitude;
return $this;
}
}
In my resources.yaml
App\Entity\Station:
collectionOperations:
get_nearby:
method: GET
path: /nearby_stations
controller: App\Action\NearbyStationsAction
normalization_context:
groups: ["read"]
swagger_context:
parameters:
- in: query
name: latitude
required: true
type: string
description: "Latitude coordonates"
schema:
type: float
- in: query
name: longitude
required: true
type: string
description: "Longitude coordonates"
schema:
type: float
itemOperations: []
I created an action controller App\Action\NearbyStationsAction
namespace App\Action;
use App\DataProvider\StationCollectionDataProvider;
use App\Entity\Station;
class NearbyStationsAction
{
public function __invoke(StationCollectionDataProvider $stationCollectionDataProvider): array
{
return $stationCollectionDataProvider->getCollection(Station::class);
}
}
And a dataProvider :
namespace App\DataProvider;
use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use App\Entity\Station;
use Doctrine\Common\Persistence\ManagerRegistry;
use Symfony\Component\HttpFoundation\RequestStack;
final class StationCollectionDataProvider implements CollectionDataProviderInterface, RestrictedDataProviderInterface
{
private $managerRegistry;
private $requestStack;
public function __construct(ManagerRegistry $managerRegistry, RequestStack $requestStack)
{
$this->managerRegistry = $managerRegistry;
$this->requestStack = $requestStack;
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return Station::class === $resourceClass;
}
public function getCollection(string $resourceClass, string $operationName = null): ?array
{
// I will use Request to get query params for findByDistanceAndCoordonates method
$manager = $this->managerRegistry->getManagerForClass($resourceClass);
$repository = $manager->getRepository($resourceClass);
return $repository->findByDistanceAndCoordonates(6, -0.863621, -108.572197);
}
}
The result is almost pretty good… I’ve the good object returned but is returned fully… My groups serialization aren’t work (cf. resources.yaml normalization_context) My groups are defined in config/serialization/Station.yaml
App\Entity\Station:
attributes:
id:
groups: ['read']
latitude:
groups: ['read']
If i use default GET collection operation it works well, good attributes are displayed in my result. But with my custom, i’ don’t know how apply context serialization to my result. Perhaps i’m not in the right way too… I’m loosing myself between custom operation, DTO and filters… Maybe i suppose do it by an other way.
If someone could explain me how to do with the good practice that’ll be awesome 😃
Thanks for reading me. Thanks for your help.
BenWa.
Issue Analytics
- State:
- Created 5 years ago
- Reactions:1
- Comments:5 (2 by maintainers)
Hi,
I am facing the same issue,
A possible solution is just to focus on the custom operation so no DataProvider is needed here
Look at the following example:
I think we can close this, tell me if that’s not the case I’ll re-open.