Php 使用Api平台定制ItemDataProvider

Php 使用Api平台定制ItemDataProvider,php,symfony,symfony4,api-platform.com,Php,Symfony,Symfony4,Api Platform.com,我尝试用Symfony 4.3和Api平台做一个演示应用程序 我创建了一个名为Event的实体: /** * @ApiResource( * itemOperations={ * "put"={"denormalization_context"={"groups"={"event:update"}}}, * "get"={ * "normalization_context"={"groups"={"event:rea

我尝试用Symfony 4.3和Api平台做一个演示应用程序

我创建了一个名为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;
    }
}
对于事件$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);
    }
在问题的前一段代码中,您没有提到事件类有一个构造函数,因此基本上当ApiPlatform尝试提取索引或id属性时,响应为null,然后restfull结构被破坏。它们无法生成如下所示的restfull url:

http://example/api/event/null ????
class
{
     private $id;
     public function __constructor($id)
     {
         $this->id = $id;
     }
}
尝试在构造函数中设置$id参数,例如:

http://example/api/event/null ????
class
{
     private $id;
     public function __constructor($id)
     {
         $this->id = $id;
     }
}
另外,由于注释不是必须的,因此在Apiplate中返回getItem中的确切类,您可以尝试以下方法:

public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
    {
        return ['id'=> $id]
    }

更新:

添加标识符

@ApiProperty(identifier=true)

向我的实体添加构造函数并不能解决这个问题,现在没有以前的IRI错误,但是除了id之外的所有字段都是空的。所以它仍然无法检索数据。@RaKoDev Symfony有自动连线功能,在某些情况下,您需要启用该服务,因此基本上您需要执行以下操作:抱歉,我将修改我的answer@RaKoDev基本上是一个DTO,用于将实体或实体组转换为分组数据,在这种情况下,您可以在Api中启用类型或类,但是没有生成一个表或类,它就变成了一个实体,并手动设置数据。是的,这是我最后已经做过的。我在这里遵循API平台文档中的示例:我想知道为什么它不能像示例中那样工作。请在您的答案中添加一些解释,以便其他人可以从中学习