dualmedia / symfony-request-dto-bundle
Symfony bundle which provides DTO object functionality and resolving
Installs: 819
Dependents: 0
Suggesters: 0
Security: 0
Stars: 6
Watchers: 2
Forks: 3
Open Issues: 1
Type:symfony-bundle
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
This bundle aims to lower the burden of typechecking, casting, loading entities and related annoyances of using requests in your api.
Bundle will automatically hook into Doctrine ORM Bundle and Nelmio API Docs Bundle so no additional configuration should be needed.
Install
Simply composer require dualmedia/symfony-request-dto-bundle
, if applicable your Doctrine entity managers will be detected automatically and used as default providers for classes to be loaded with your requests if needed.
Then add the bundle to your config/bundles.php
file like so
return [ Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true], // other bundles ... DualMedia\DtoRequestBundle\DtoBundle::class => ['all' => true], ];
Upgrades
See CHANGES.md
Usage
- Create a DTO class for your request
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; }
- Add your dto as a controller argument
class MyController extends \Symfony\Bundle\FrameworkBundle\Controller\AbstractController { public function myAction(MyDto $dto): \Symfony\Component\HttpFoundation\Response { // your dto here is already validated! } }
Application wide handling of DTO issues
If you wish to automatically return a 4XX response code when a dto has failed validation you may use something like the following:
# 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 } } }
If you want to map a class-wide assert to a path without having to directly modify the constraint itself you may wrap it in 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; }
Docs
Currently no documentation is available, but will be added in the future. For the time being see the DTO models for tests