dualmedia/symfony-request-dto-bundle

Symfony 扩展包,提供 DTO 对象功能和解析

3.1.0 2024-07-18 07:00 UTC

This package is auto-updated.

Last update: 2024-09-18 07:24:36 UTC


README

Code Coverage Packagist Downloads

此扩展包旨在减轻使用请求在 API 中进行类型检查、类型转换、加载实体及相关烦恼的负担。

扩展包将自动集成Doctrine ORM 扩展包Nelmio API Docs 扩展包,因此不需要额外配置。

安装

简单使用 composer require dualmedia/symfony-request-dto-bundle,如果适用,您的 Doctrine 实体管理器将自动检测并用作加载请求中类时的默认提供者。

然后,将扩展包添加到您的 config/bundles.php 文件中,如下所示

return [
    Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
    // other bundles ...
    DualMedia\DtoRequestBundle\DtoBundle::class => ['all' => true],
];

升级

查看CHANGES.md

用法

  1. 为您的请求创建一个 DTO 类
use \DualMedia\DtoRequestBundle\Attributes\Dto\Path;
use \DualMedia\DtoRequestBundle\Model\AbstractDto;

class MyDto extends AbstractDto
{
    public int|null $myVar = null;
    
    #[Path("custom_path")]
    public string|null $myString = null;
}
  1. 将您的 dto 添加为控制器参数
class MyController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController
{
    public function myAction(MyDto $dto): \Symfony\Component\HttpFoundation\Response
    {
        // your dto here is already validated!
    }
}

全局处理 DTO 问题

如果您希望当 DTO 验证失败时自动返回 4XX 响应代码,您可以使用如下方法

# config/services.yaml
App\EventSubscriber\ErrorSubscriber:
  decorates: exception_listener
  arguments:
    - '@App\EventSubscriber\ErrorSubscriber.inner'
class ErrorSubscriber implements \Symfony\Component\EventDispatcher\EventSubscriberInterface
{
    public function __construct(
        private readonly ErrorListener $decorated
    ) {
    }

    public static function getSubscribedEvents(){
        return [
            \Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent::class => 'onControllerArguments',
        ];
    }
    
    public function onControllerArguments(
        ControllerArgumentsEvent $event
    ): void {
        $this->decorated->onControllerArguments($event);

        $violationList = new ConstraintViolationList();

        foreach ($event->getArguments() as $argument) {
            if ($argument instanceof DtoInterface
                && !$argument->isOptional()
                && !$argument->isValid()) {
                $violationList->addAll($argument->getConstraintViolationList());
            }
        }

        if (0 !== $violationList->count()) {
            throw new ValidatorException($violationList); // handle and display, or just do whatever really
        }
    }
}

如果您想将类级别的断言映射到路径而不直接修改约束本身,您可以在 MappedToPath 中包装它

use \DualMedia\DtoRequestBundle\Constraints\MappedToPath;
use \DualMedia\DtoRequestBundle\Model\AbstractDto;
use Symfony\Component\Validator\Constraints as Assert;

#[MappedToPath(
    'property',
    new Assert\Expression(
        'this.property != null',
        message: 'This property cannot be null'
    )
)]
class MyDto extends AbstractDto
{
    public int|null $property = null;
}

文档

目前没有可用的文档,但将在未来添加。目前请参阅测试用例的 DTO 模型