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

禁用 ApiPlatform 中输入对象的自动验证

如何解决禁用 ApiPlatform 中输入对象的自动验证

我已经使用 Symfony messenger 为 CQRS 配置了 ApiPlatform,如下所述:https://api-platform.com/docs/core/messenger/#using-messenger-with-an-input-object。我的实体看起来类似于:

#[
    ORM\Entity(),ORM\Table(name: '`presents`'),ApiResource(
        collectionoperations: [
            'get','post' => [
                'messenger' => 'input','input' => AddPresentRequest::class,],itemOperations: ['get'],),]
class Present
{
    // ...

然后我向 DTO 对象添加了一些 symfony 约束:

use Symfony\Component\Validator\Constraints as Assert;

final class AddPresentRequest
{
    #[Assert\NotBlank]
    #[Assert\Length(
        max: 180
    )]
    private string $name;

    // ...

现在 ApiPlatform 会在将请求实体传递给消息总线之前自动对其进行验证。

我希望它不要那样做。

原因是虽然验证对 API 请求非常有效,但它对 API 请求有效。我希望在执行此操作时也运行验证:

/** @var MessageBusInterface $messageBus */
$messageBus->dispatch(new AddPresentRequest($name));  // api-platform doesn't trigger validation

向消息总线添加验证很容易,我只需要按照 in this symfony-docs issue 的描述启用 ValidationMiddleware。这样,信使总是触发验证。

然而,这意味着对于 API 请求,验证器运行两次 - 一次由 ApiPlatform 触发,然后再次由 ValidationMiddleware 触发。这就是为什么我需要告诉 ApiPlatform 冷静一下,我明白了。

我在 ApiPlatform 文档中找不到关于如何禁用自动验证的任何内容。我可以用自定义的东西替换验证器的文档 mention,我认为这可能会提供线索,但不幸的是,没有关于如何替换它的实际信息。

我发现的一种解决方法是我可以在实体上设置一个虚假的验证组:validationGroups: ['non-existent']。但这并不完美,因为虽然没有检查约束,但验证器仍会运行并解析实体两次。

如何禁用 ApiPlatform 的自动验证,以便我可以在其他地方处理验证?

解决方法

您可以在操作配置中禁用 the built in validation event listener

#[
    ApiResource(
        collectionOperations: [
            'post' => [
                'messenger' => 'input','input' => AddPresentRequest::class,'validate' => false,//disables the validation event listener
            ],],),]

这应该会阻止 API 平台(自动)验证您的输入 DTO。

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