DataProvider - API 平台上的 getSubresource

DataProvider - getSubresource on API Platform

我想使用 subresourceDataProvider 来更改数据库中的一些数据。 但是当我这样做的时候,它进入了一个无限循环?如何停止?

<?php
namespace App\DataProvider;

use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;

class MessageDataProvider implements SubresourceDataProviderInterface
{
    private $subresourceDataProvider;

    public function __construct(SubresourceDataProviderInterface $subresourceDataProvider)
    {
        $this->subresourceDataProvider = $subresourceDataProvider;
    }
    public function getSubresource(string $resourceClass, array $identifiers, array $context, string $operationName = null)
    {
        return $this->subresourceDataProvider->getSubresource($resourceClass, $identifiers, $context, $operationName);
    }
}

class MessageDataProvider 实现 SubresourceDataProviderInterface,这也是构造函数中的一个参数 - symfony 可能会尝试通过将 MessageDataProvider 放入来自动装配 SubresourceDataProviderInterface构造函数。但是为了将 MessageDataProvider 放入构造函数中,它必须首先构建这种类型的实例。为此,需要调用 MessageDataProvider 构造函数。这就是无限循环的创建方式。

如果您打算注入 SubresourceDataProvider 的实体,您可以显式配置 MessageDataProvider 服务。 Link 到 docs

我在这个 link

上找到了解决方案

https://github.com/api-platform/core/issues/2816#issuecomment-494579509

<?php

namespace App\DataProvider;

use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;
use App\Entity\Note;

class NoteSubresourceDataProvider implements RestrictedDataProviderInterface, SubresourceDataProviderInterface
{
    private $alreadyInvoked = false;
    private $subresourceDataProvider;

    public function __construct(SubresourceDataProviderInterface $subresourceDataProvider)
    {
        $this->subresourceDataProvider = $subresourceDataProvider;
    }

    public function getSubresource(string $resourceClass, array $identifiers, array $context, string $operationName = null)
    {
        $this->alreadyInvoked = true;

        $collection = $this->subresourceDataProvider->getSubresource($resourceClass, $identifiers, $context);

        return $collection;
    }

    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
    {
        return !$this->alreadyInvoked && Note::class === $resourceClass;
    }
}