我想知道哪些是好的做法:
假设我有两个实体,一个多个。 两者都是ApiResources,都有一个输出DTO。 所以两个都有变压器。
<?php
/**
* @ORM\Entity
* @ApiResource(
* output="Dto\Foo"
* )
*/
class Foo
{
private int $id;
/**
* @ORM\ManyToOne(targetEntity="Bar")
*/
private Bar $bar;
}
问题是,当我将实体Foo转换为DTO Foo时,我想用Bar DTO来水化它,而不是Bar实体。 但因为我用一个实体来水化它,我就有了一个酒吧实体。 在这个过程的后面,Bar实体被一个Bar DTO替换,ApiPlateform正常工作,但是我的问题是:Bar属性类型会随着时间的推移而被修改(而且它不能进行类型提示)。 在我看来很脏,不是吗?
插图:
Transofer
<?php
use ApiPlatform\Core\DataTransformer\DataTransformerInterface;
class FooEntityToFooDToTransormer implements DataTransformerInterface
{
public function transform($object, string $to, array $context = [])
{
return new FooDto($object);
// maybe there is a better way to hydrate FooDto, by getting directly a BarDto here ?
}
}
DTO:
<?php
namespace Dto;
class Foo
{
public int $id;
// problem is I cant typehint here
public $bar;
public function __construct(FooEntity $fooEntity)
{
$this->id = $fooEntity->getId();
$this->bar = $fooEntity->getBar(); // <-- return a Bar entity, transformed later by ApiPlatform into a Bar DTO.
}
}
有没有一种方法或一个好的做法来适当地水合一个实体的DTO,特别是关于关系?
我想这里有两种可能的解决方案,一种是通过多一个参数扩展DTO的构造函数签名并调整转换器,另一种是在DTO的构造函数中进行转换:
<?php
namespace Dto;
class FooDto
{
public BarDto $bar;
// first variant
public function __construct(FooEntity $fooEntity, BarDto $barDto)
{
$this->id = $fooEntity->getId();
$this->bar = $barDto;
}
// second
public function __construct(FooEntity $fooEntity)
{
$this->id = $fooEntity->getId();
$this->bar = new BarDto($fooEntity->getBar());
}
}