dualmedia / symfony-request-dto-bundle
Symfony 扩展包,提供 DTO 对象功能和解析
3.1.0
2024-07-18 07:00 UTC
Requires
- php: ^8.1
- symfony/event-dispatcher: ^5.4|^6.2
- symfony/framework-bundle: ^5.4|^6.2
- symfony/property-access: ^5.4|^6.2
- symfony/property-info: ^5.4|^6.2
- symfony/validator: ^5.4|^6.2
Requires (Dev)
- ext-simplexml: *
- doctrine/doctrine-bundle: ^2
- doctrine/orm: ^2|^3
- friendsofphp/php-cs-fixer: ^3
- matthiasnoback/symfony-dependency-injection-test: ^4.3
- nelmio/api-doc-bundle: ^4
- pedrotroller/php-cs-custom-fixer: ^2
- phpstan/phpstan: ^1
- phpunit/phpunit: ^9.5
- symfony/expression-language: ^5.4|^6.2
- symfony/phpunit-bridge: ^5.4|^6.2
- symfony/stopwatch: ^5.4|^6.2
- symfony/web-profiler-bundle: ^5.4|^6.2
- vimeo/psalm: ^5
Suggests
- doctrine/doctrine-bundle: Symfony's ORM of choice
- nelmio/api-doc-bundle: Adds api docs for endpoints for your DTOs
Conflicts
README
此扩展包旨在减轻使用请求在 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], ];
升级
用法
- 为您的请求创建一个 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; }
- 将您的 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 模型