带有 Api 平台的自定义 ItemDataProvider [英] Custom ItemDataProvider with Api Platform

查看:25
本文介绍了带有 Api 平台的自定义 ItemDataProvider的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试用 Symfony 4.3 & 做一个演示应用程序接口平台

I try to do a demo app with Symfony 4.3 & Api Platform

我创建了一个名为 Event 的实体:

I created an entity called 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 类,我的目标是在将实体发送到响应之前做其他事情.

And an EventItemDataProvider class, my goal is to do something else before sending the entity to the response.

<?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) 我有这个错误:

When it comes to Event($id) I have this error:

无法为 \"App\Entity\Event\" 类型的项目生成 IRI

Unable to generate an IRI for the item of type \"App\Entity\Event\"

我的代码有什么问题吗?

What do you thing is wrong with my code?

推荐答案

我觉得是关于逻辑的,api 平台使用了一个 restfull 组件.当您拦截 getItem 时,基本上您正在使用此路线:

I think is about the logic, api platform uses a restfull component. When you intercept the getItem basically you are using this route:

http://example/api/event/id

这部分是我们需要尝试弄清楚发生了什么

in this part is how we need to try to figure what is happening

public function getItem(string $resourceClass, $id, string $operationName = null, array $context = []): ?Event
    {
        return new Event($id);
    }

在前面的问题代码中,你没有提到Event类有一个构造函数,所以基本上当ApiPlatform尝试提取index或id属性时,响应为空,然后restfull结构被破坏.他们不能像这样生成restfull url:

in the previous code of the question, you didnt mention about the Event class has a contructor, so basically when the ApiPlatform try to extract the index or id attribute the response is null, and then the restfull structure is broken. They cannot generate the restfull url like this:

http://example/api/event/null ????

尝试在构造函数中设置 $id 参数,例如像这样:

Try to set in a constructor the $id parameter for example like this:

class
{
     private $id;
     public function __constructor($id)
     {
         $this->id = $id;
     }
}

此外,作为注释不是强制返回 ApiPlatform 中 getItem 中的确切类,您可以尝试:

also as a comment is not mandatory return the exact Class in getItem in ApiPlatform, you can try with this:

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);
    }
}

这篇关于带有 Api 平台的自定义 ItemDataProvider的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆