php - 使用 Api 平台自定义 ItemDataProvider
问题描述
我尝试用 Symfony 4.3 & Api Platform 做一个演示应用
我创建了一个名为 Event 的实体:
/**
* @ApiResource(
* itemOperations={
* "put"={"denormalization_context"={"groups"={"event:update"}}},
* "get"={
* "normalization_context"={"groups"={"event:read", "event:item:get"}}
* },
* "delete"
* },
* collectionOperations={"get", "post"},
* normalizationContext={"groups"={"event:read"}, "swagger_definition_name"="Read"},
* denormalizationContext={"groups"={"event:write"}, "swagger_definition_name"="Write"},
* shortName="Event",
* attributes={
* "pagination_items_per_page"=10,
* "formats"={"jsonld", "json", "csv", "jsonhal"}
* }
* )
* @ORM\Entity(repositoryClass="App\Repository\EventRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Event
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"event:read", "event:item:get"})
*/
private $id;
...
public function getId(): ?int
{
return $this->id;
}
...
还有一个 EventItemDataProvider 类,我的目标是在将实体发送到响应之前执行其他操作。
<?php
namespace App\DataProvider;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
use App\Entity\Event;
final class EventItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
{
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return Event::class === $resourceClass;
}
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?Event
{
// Retrieve the blog post item from somewhere then return it or null if not found
return new Event($id);
// return null;
}
}
当谈到 Event($id) 我有这个错误:
无法为 \"App\Entity\Event\" 类型的项目生成 IRI
你觉得我的代码有什么问题?
解决方案
我认为是关于逻辑,api平台使用了一个restfull组件。当您拦截 getItem 时,基本上您正在使用此路线:
http://example/api/event/id
在这部分中,我们需要尝试弄清楚正在发生的事情
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?Event
{
return new Event($id);
}
在问题的前面代码中,您没有提到 Event 类有一个构造函数,所以基本上当 ApiPlatform 尝试提取 index 或 id 属性时,响应为空,然后 restfull 结构被破坏。他们不能像这样生成 restfull url:
http://example/api/event/null ????
尝试在构造函数中设置 $id 参数,例如:
class
{
private $id;
public function __constructor($id)
{
$this->id = $id;
}
}
同样作为注释不是强制性的,在 ApiPlatform 的 getItem 中返回确切的类,您可以尝试以下操作:
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
{
return ['id'=> $id]
}
更新:
<?php
namespace App\DataProvider;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Event;
final class EventItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
{
private $repository;
/**
* UserDataProvider constructor.
*/
public function __construct(EntityManagerInterface $entityManager)
{
$this->repository = $entityManager->getRepository(Event::class);
}
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return Event::class === $resourceClass;
}
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?Event
{
// Retrieve the blog post item from somewhere then return it or null if not found
return $this->repository->find($id);
}
}
推荐阅读
- grails - Grails4 GORM Domains - 连接表为空
- reactjs - 如何将 React 框架导入 vscode 源代码项目以创建 UI 组件?
- reactjs - 我用过这个命令 npm runeject 它不工作
- azure-web-app-service - Azure Webapp(Windows):对外部链接的 URL 重写返回错误
- bash - 在 bash 中有效获取命令输出的一致语法?
- android - 如何在 Android Studio 中通过 logcat 或终端查看 Google Analytics 测量协议(调试)
- django - django如何将上传到数据库的文件的链接和实际文件的链接保存在django的特定文件夹中
- function - Kotlin - 将 sortBy 参数作为函数参数传递
- java - 我如何使用 volley 从服务器发送和验证参数?
- python - 按元素对列表组合求和