禁用@Embedded 对象的 jsonld 元数据

Disable jsonld metadata for @Embedded objects

我一直在寻找这个(看似简单的)问题的答案,但到目前为止我找到了 none。

我有一个这样设计的 VatAmount :

/**
 * ValueObject defining the amount both with and without VAT.
 * @ORM\Embeddable
 * @property int $total
 * @property int|null $withoutVat
 * @Assert\EnableAutoMapping()
 */
class VatAmount
{
    /**
     * TTC
     * @ORM\Column(type="integer")
     * @Assert\NotNull()
     * @Assert\GreaterThanOrEqual(50)
     */
    protected $total = 0;

    /**
     * HT
     * @ORM\Column(type="integer", nullable=true)
     */
    protected $withoutVat;

    ...

然后我在多个实体中使用它:

class Bill
{
    /**
     * @Embedded(class=VatAmount::class)
     */
    private $amount;

    ...
}

最后,我将它添加到我的序列化组中:

App\Entity\Billing\Bill:
  attributes:
    amount:
      groups: ["bill:read", "order:detail"]
   ...

App\Entity\Embeddable\VatAmount:
  attributes:
    total:
      groups: ["amount:read", "amount:write"]
    withoutVat:
      groups: ["amount:read", "amount:write"]

这意味着 VatAmount 不仅不是 ApiResource,甚至不是真正的实体,也没有自己的 ID。

在我从 api-platform 2.5.7 升级到 2.6.3 之前,jsonld 元数据(@id、@context、@type)存在于 OpenApi 文档中,但在我实际获取资源时却没有。我只是删除了 OpenApi 字段,一切都很好。

但是现在我升级了,每当我获取资源时,我都会得到:

  "amount" => array:4 [
    "@type" => "VatAmount"
    "@id" => "_:46842"
    "total" => 1000
    "withoutVat" => 800
  ]

我什至不确定 _:46842 指的是什么,我希望它消失。

所以我的问题是:有什么方法可以为特定 class 或嵌套资源禁用这些字段?

我试过了:

两者似乎都是死胡同,我找不到任何关于在这些上下文中接受哪些字段的文档。

感谢您的帮助。

我找到了它的来源。奇怪的是,负责此功能的所有代码似乎已经存在了很长时间,所以我不确定最新更新发生了什么变化以使其正常工作。

每当匿名嵌入对象被序列化时,ObjectNormalizer::normalize() 就会被调用。这个 class 注入了一个 AnonymousContextBuilderInterface(默认情况下,ContextBuilder),它将传递给 JsonLdContextTrait 以构建上下文。 ContextBuilder::getAnonymousResourceContext() 方法将 return 一个数组,其中 @id 是 PHP 的内部 ID :

'@id' => $context['iri'] ?? '_:'.(\function_exists('spl_object_id') ? spl_object_id($object) : spl_object_hash($object)),

我还没有找到任何配置此行为的方法。

考虑到这一点,我创建了一个 VoidContextBuilder,其中 return 是 getAnonymousResourceContext() 上的一个空数组,并通过编译器传递将其注入到 ContextBuilder 的位置:

$def = $container->getDefinition('api_platform.jsonld.normalizer.object');
$def->setArgument('$anonymousContextBuilder', new Reference('App\Util\VoidContextBuilder'));

这有效,但似乎无法修复 OpenApi 视图,所以我保留了之前的代码:

if (substr($name, 0, 9) === 'VatAmount') {
 unset($schema['properties']['@context']);
 unset($schema['properties']['@id']);
 unset($schema['properties']['@type']);
}

请告诉我是否有更好、更安全的方法来摆脱匿名资源的 jsonld 上下文。