Пользовательский ItemDataProvider с платформой Api - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь создать демонстрационное приложение с 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), у меня есть эта ошибка:

Невозможно сгенерировать IRI для элемента типа \ "App \ Entity \ Event \"

Что тебе не так с моим кодом?

1 Ответ

1 голос
/ 04 июля 2019

Я думаю о логике, платформа 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, ответ имеет значение null, а затем структура restfull нарушается.Они не могут сгенерировать повторный URL-адрес следующим образом:

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

Попробуйте установить в конструкторе параметр $ id, например, следующим образом:

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

, так как комментарий не является обязательным. Returnточный класс в getItem в ApiPlatform, вы можете попробовать это:

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...