-
-
Notifications
You must be signed in to change notification settings - Fork 940
Closed
Labels
Description
Is it possible to use a DTO without registering it as ApiResource? I would like to expose a DTO from my Entity but it is not passed to SchemaBuilder unless I register it as ApiResource. This however requires to add an identifier to the DTO.
It works perfectly on JSON endpoints since coordinates are being serialized properly. This does not happen for GraphQL because API Platform does not know about the DTO at all and does not build schema for this.
Consider example entity:
<?php
namespace App\Entity;
use App\DTO\Coordinates;
use Ramsey\Uuid\UuidInterface;
class Country
{
/** @var UuidInterface */
protected $id;
/** @var float|null */
protected $latitude;
/** @var float|null */
protected $longitude;
/** @var string */
protected $name;
public function getId(): UuidInterface
{
return $this->id;
}
public function getLatitude(): ?float
{
return $this->latitude;
}
public function setLatitude(?float $latitude): Country
{
$this->latitude = $latitude;
return $this;
}
public function getLongitude(): ?float
{
return $this->longitude;
}
public function setLongitude(?float $longitude): Country
{
$this->longitude = $longitude;
return $this;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): Country
{
$this->name = $name;
return $this;
}
public function setCoordinates(Coordinates $coordinates): Country
{
return $this->setLatitude($coordinates->getLatitude())
->setLongitude($coordinates->getLongitude());
}
public function getCoordinates(): Coordinates
{
return new Coordinates($this->getLatitude(), $this->getLongitude());
}
public function __toString(): string
{
return $this->getName();
}
}and Coordinates DTO:
<?php
namespace App\DTO;
use ApiPlatform\Core\Annotation\ApiProperty;
class Coordinates
{
/** @var float */
protected $latitude;
/** @var float */
protected $longitude;
public function __construct(float $latitude, float $longitude)
{
$this->latitude = $latitude;
$this->longitude = $longitude;
}
public function getLatitude(): float
{
return $this->latitude;
}
public function setLatitude(float $latitude): Coordinates
{
$this->latitude = $latitude;
return $this;
}
public function getLongitude(): float
{
return $this->longitude;
}
public function setLongitude(float $longitude): Coordinates
{
$this->longitude = $longitude;
return $this;
}
/**
* This is needed only to register it as Api Resource
* @ApiProperty(identifier=true)
*/
public function getId()
{
return md5($this->getLatitude().' '.$this->getLongitude());
}
}Hack to make Coordinates show in GraphQL endpoints:
resources:
# [...]
App\DTO\Coordinates:
shortName: Coordinate
attributes:
normalization_context:
groups: ['read']
collectionOperations: {}
itemOperations: {}epourail and kiler129