微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

禁用@Embedded 对象的 jsonld 元数据

如何解决禁用@Embedded 对象的 jsonld 元数据

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

我有一个 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 指的是什么,我希望它消失。

所以我的问题是:有没有办法禁用特定类或嵌套资源的这些字段?

我试过了:

  • ApiProperty(jsonldContext={})
  • 使用 ApiResource(hydraContext={})

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

感谢您的帮助。

解决方法

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

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

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

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

考虑到这一点,我创建了一个 VoidContextBuilder,它在 getAnonymousResourceContext() 上返回一个空数组,并使用编译器传递将它注入到 ContextBuilder 的位置:

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

这似乎无法修复 OpenApi 视图。我还必须保留之前的代码:

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。