为了路由版本化和实体与API输出之间更好的分离,我做了一个资源,它不是一个由提供者链接到该实体的实体。A想添加一些过滤器并进行分页,但似乎我不能原生地。
例如,我有一个实体:
<?php
namespace App\Entity;
use App\Repository\UserApiKeyRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Blameable\Traits\BlameableEntity;
use Gedmo\Mapping\Annotation as Gedmo;
use Gedmo\Timestampable\Traits\TimestampableEntity;
#[ORM\Entity(repositoryClass: TreasureRepository::class)]
#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', timeAware: true, hardDelete: false)]
class Treasure
{
use BlameableEntity;
use TimestampableEntity;
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private int $id;
#[ORM\ManyToOne(inversedBy: 'treasures')]
#[ORM\JoinColumn(referencedColumnName: 'owner_id', nullable: false)]
private Owner $owner;
#[ORM\Column(length: 255)]
private string $name;
#[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 2)]
private string $value;
#[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)]
private ?\DateTimeInterface $deletedAt = null;
我做了一个资源:
<?php
namespace App\ApiResource\V1;
use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\Delete;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\GetCollection;
use ApiPlatform\Metadata\Link;
use ApiPlatform\Metadata\Post;
use App\Entity\Owner;
#[ApiResource(
uriTemplate: '/owners/{owner_id}/treasures/{id}.{_format}',
shortName: 'Treasures',
operations: [
new Get(),
new Delete(
processor: TreasureProcessor::class
)
],
uriVariables: [
'owner_id' => new Link(
fromProperty: 'treasures',
fromClass: Owner::class
),
'id' => new Link(
fromClass: self::class
)
],
provider: TreasureProvider::class
)]
#[ApiResource(
uriTemplate: '/owners/{owner_id}/treasures.{_format}',
shortName: 'Treasures',
operations: [
new GetCollection(
normalizationContext: ['groups' => 'list']
),
new Post(
denormalizationContext: ['groups' => 'create'],
processor: TreasureProcessor::class,
)
],
uriVariables: [
'owner_id' => new Link(
fromProperty: 'treasures',
fromClass: Owner::class
)
],
provider: TreasureProvider::class
)]
class TreasureResource
{
#[Groups(['list'])]
private ?int $id;
#[Groups(['list', 'create'])]
private string $name;
#[Groups(['list', 'create'])]
private string $value;
private ?Owner $owner;
public function __construct(
string $name,
string $value,
?Owner $owner = null,
?int $id = null
)
{
$this->id = $id;
$this->name = $name;
$this->value = $value;
$this->owner = $owner;
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function getValue(): string
{
return $this->value;
}
public function getOwner(): ?Owner
{
return $this->owner;
}
}
像这样我没有分页也没有过滤器。如果我添加了过滤器属性的名称,例如
#[ApiFilter(SearchFilter::class, strategy: 'partial')]
我有一个错误
在null上调用成员函数getClassMetadata()
另外,我试图添加一个分页到我的提供程序,但效果不好,我没有真实的结果“hydra:totalItems”,显示当前页面的总数,而不是所有的结果,我没有json-ld提供的上一页,下一页,总页数信息。我没有看到一种方法来设置ApiPlatform的分页数据。
以下是我的供应商的示例:
$owner = $this->ownerRepository->find($uriVariables['owner_id']);
/** ApiPlatform\State\Pagination\Pagination $this->pagination */
$page = $this->pagination->getPage($context);
$itemsPerPage = $this->pagination->getLimit($operation, $context);
$treasures = $this->treasureRepository->findByOwnerPaginated($owner, $page, $itemsPerPage);
return $this->collectionToResources($treasures); //returns an array
任何人遇到这些问题,并能够解决或绕过他们?我希望我可以使用ApiPlatform属性开箱即用,即使这种编码方式
1条答案
按热度按时间h79rfbju1#
我一直在寻找同样的东西,我发现它现在可以从v3.1.8.要实现它,你必须使用
stateOptions
:源码:https://github.com/api-platform/core/pull/5550/files#diff-15a5e5dac807773e03253202f2a43d4e695aa7ac2f43874116741a6d9b4c69ca