{"id":18408627,"url":"https://github.com/artyuum/request-dto-mapper-bundle","last_synced_at":"2025-04-07T09:32:59.027Z","repository":{"id":41173486,"uuid":"337970744","full_name":"artyuum/request-dto-mapper-bundle","owner":"artyuum","description":"This bundle provides an easy way to automatically map the incoming request data to a DTO and optionally validate it.","archived":false,"fork":false,"pushed_at":"2024-02-14T10:48:32.000Z","size":36,"stargazers_count":51,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-09-17T00:17:39.462Z","etag":null,"topics":["api","bundle","dto","dto-mapper","object-mapper","php","php8","symfony","symfony-bundle"],"latest_commit_sha":null,"homepage":"https://packagist.org/packages/artyuum/request-dto-mapper-bundle","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/artyuum.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-11T08:32:30.000Z","updated_at":"2024-05-09T20:29:42.000Z","dependencies_parsed_at":"2024-02-14T11:47:28.843Z","dependency_job_id":null,"html_url":"https://github.com/artyuum/request-dto-mapper-bundle","commit_stats":{"total_commits":20,"total_committers":2,"mean_commits":10.0,"dds":0.09999999999999998,"last_synced_commit":"eac071ccf93f5f93860f902c4d12c22f5511b2ac"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artyuum%2Frequest-dto-mapper-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artyuum%2Frequest-dto-mapper-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artyuum%2Frequest-dto-mapper-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artyuum%2Frequest-dto-mapper-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artyuum","download_url":"https://codeload.github.com/artyuum/request-dto-mapper-bundle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247626493,"owners_count":20969315,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","bundle","dto","dto-mapper","object-mapper","php","php8","symfony","symfony-bundle"],"created_at":"2024-11-06T03:20:04.387Z","updated_at":"2025-04-07T09:32:58.632Z","avatar_url":"https://github.com/artyuum.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Request DTO Mapper Bundle\n![image](https://user-images.githubusercontent.com/17199757/193117824-e5eec5b6-f4c0-4c96-af9b-fa2bc6096806.png)\n\nThis bundle provides an easy way to automatically map the incoming request data to a DTO and optionally validate it. It's using the powerful [Serializer](https://symfony.com/doc/current/components/serializer.html) component under the hood along with the [Validator](https://symfony.com/doc/current/components/validator.html) component (optional).\n\n## Requirements\n- PHP ^8.0\n- Symfony ^5.0 or ^6.0\n\n## Installation\n```bash\ncomposer require artyuum/request-dto-mapper-bundle\n```\n\n## Configuration\n```yml\n# config/packages/artyum_request_dto_mapper.yaml\nartyum_request_dto_mapper:\n\n    # Used if the attribute does not specify any (must be a FQCN implementing \"\\Artyum\\RequestDtoMapperBundle\\Extractor\\ExtractorInterface\").\n    default_extractor: null # Example: Artyum\\RequestDtoMapperBundle\\Extractor\\JsonExtractor\n\n    # The configuration related to the denormalizer (https://symfony.com/doc/current/components/serializer.html).\n    denormalizer:\n\n        # Used when mapping the request data to the DTO if the attribute does not set any.\n        default_options: []\n\n        # Used when mapping the request data to the DTO (merged with the values passed by the attribute or \"default_options\").\n        additional_options: []\n\n    # The configuration related to the validator (https://symfony.com/doc/current/validation.html).\n    validation:\n\n        # Whether to validate the DTO after mapping it.\n        enabled: false\n\n        # Used when validating the DTO if the attribute does not set any.\n        default_groups: []\n\n        # Used when validating the DTO (merged with the values passed by the attribute or \"default_groups\").\n        additional_groups: []\n\n        # Whether to throw an exception if the DTO validation failed (constraint violations).\n        throw_on_violation: true\n```\n\n## Usage\nThis is a simple step-by-step example of how to make a DTO that will be used by the bundle.\n\n1. Create the DTO that represents the structure of the content the user will send to your controller. \n```php\nclass PostPayload {    \n    /**\n     * @Assert\\Sequentially({\n     *     @Assert\\NotBlank,\n     *     @Assert\\Type(\"string\")\n     * })\n     *\n     * @var string|null\n     */\n    public $content;\n}\n```\n\n2. Inject the DTO into your controller \u0026 configure it using the [Dto attribute](/src/Attribute/Dto.php).\n\n```php\nuse Artyum\\RequestDtoMapperBundle\\Attribute\\Dto;\nuse Artyum\\RequestDtoMapperBundle\\Extractor\\JsonExtractor;\n\nclass CreatePostController extends AbstractController\n{\n    #[Dto(extractor: JsonExtractor::class, subject: PostPayload::class, validate: true)]\n    public function __invoke(PostPayload $postPayload): Response\n    {\n        // At this stage, your DTO has automatically been mapped (from the JSON input) and validated.\n        // Your controller can safely be executed knowing that the submitted content\n        // matches your requirements (defined in your DTO through the validator constraints).\n    }\n}\n```\n\n**Alternatively**, you can set the attribute directly on the argument:\n```php\npublic function __invoke(#[Dto(extractor: JsonExtractor::class, validate: true)] PostPayload $postPayload): Response\n{\n}\n```\n\nIf you have set some default options in the configuration file (the default extractor to use, whether to enable the validation), you can even make it shorter:\n```php\npublic function __invoke(#[Dto] PostPayload $postPayload): Response\n{\n}\n```\n\n3. That's it!\n\n## Attribute\nThe [Dto attribute](src/Attribute/Dto.php) has the following seven properties:\n\n### 1. Extractor\nThe FQCN (Fully-Qualified Class Name) of a class that implements the `ExtractorInterface`. It basically contains the extraction logic and it's called by the mapper in order to extract the data from the request.\n\nThe bundle already comes with 3 built-in extractors that should meet most of your use-cases:\n- [BodyParameterExtractor](/src/Extractor/BodyParameterExtractor.php) (extracts the data from `$request-\u003erequest-\u003eall()`)\n- [JsonExtractor](/src/Extractor/JsonExtractor.php) (extracts the data from `$request-\u003etoArray()`)\n- [QueryStringExtractor](/src/Extractor/QueryStringExtractor.php) (extracts the data from `$request-\u003equery-\u003eall()`)\n\nIf an error occurs when the `extract()` method is called from the extractor class, the [ExtractionFailedException](src/Exception/ExtractionFailedException.php) will be thrown.\n\nIf these built-in extractor classes don't meet your needs, you can implement your own extractor like this:\n\n```php\nuse Artyum\\RequestDtoMapperBundle\\Extractor\\ExtractorInterface;\nuse Symfony\\Component\\HttpFoundation\\Request;\n\nclass CustomExtractor implements ExtractorInterface\n{\n    // you can optionally inject dependencies\n    public function __construct() {\n    }\n\n    public function extract(Request $request): array\n    {\n        // your custom extraction logic here \n    }\n}\n```\nThen pass it to the `Dto` attribute like this:\n\n```php\n#[Dto(extractor: CustomExtractor::class)]\n```\n\nIf you don't set any value, the default value (defined in the bundle's configuration file) will be used.\n\n**Note:** All classes implementing `ExtractorInterface` are automatically tagged as \"artyum_request_dto_mapper.extractor\",\nand this is needed by the mapper in order to retrieve the needed extractor class instance from the container.\n\n### 2. Subject\nThe FQCN (Fully-Qualified Class Name) of the DTO you want to map (it must be present as your controller argument).\n\nThe \"subject\" property is required **only** if you're setting the attribute directly on the method. Example:\n\n```php\n#[Dto(subject: PostPayload::class)]\npublic function __invoke(PostPayload $postPayload): Response\n{\n}\n```\n\nIf you're setting the attribute on the method argument instead, the \"subject\" value can be omitted and won't be read by the mapper. Example:\n```php\npublic function __invoke(#[Dto] PostPayload $postPayload): Response\n{\n}\n```\n\n### 3. Methods\nIt can contain a single or an array of HTTP methods that will \"enable\" the mapping/validation depending on the current HTTP method. In the following example, the DTO will be mapped \u0026 validated only if the request method is \"GET\".\n```php\n#[Dto(methods: 'GET')]\n``` \nor\n```php\n#[Dto(methods: ['GET'])]\n```\n\nIf the array is empty (this is the default value), the mapper will always map the DTO and validate it.\n\n### 4. Denormalization Options\nThe options that will be passed to the [Denormalizer](https://symfony.com/doc/current/components/serializer.html) before mapping the DTO.\n\nExample:\n```php\nuse Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer;\n\n#[Dto(denormalizerOptions: [ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT =\u003e true])]\n```\n\nIf an error occurs when the `denormalize()` method is called from the Denormalizer, the [DtoMappingFailedException](src/Exception/DtoMappingFailedException.php) will be thrown.\n\n### 5. Validate\nWhether to validate the DTO (once the mapping is done). Internally, the [validator component](https://symfony.com/doc/current/validation.html) will be used, and if you do not have it installed a `LogicException` will be thrown.\n\nExample:\n```php\n#[Dto(validate: true)]\n```\n\nIf the validation failed (due to the constraint violations), the constraint violations will be available as request attribute:\n```php\n$request-\u003eattributes-\u003eget('_constraint_violations')\n```\n\nIf you don't set any value, the configured value (defined in the bundle's configuration file) will be used.\n\n### 6. Validation Groups\nThe [validation groups](https://symfony.com/doc/current/form/validation_groups.html) to pass to the validator.\n\nExample:\n```php\n#[Dto(validationGroups: ['creation'])]\n```\n\nIf you don't set any value, the configured value (defined in the bundle's configuration file) will be used.\n\n### 7. Throw on violation\nWhen the validation failed, the [DtoValidationFailedException](/src/Exception/DtoValidationFailedException.php) will be thrown, and you will be able to get a list of these violations by calling the `getViolations()` method.\n\nSetting the value to `false` will prevent the exception from being thrown, and your controller will still be executed.\n\nExample:\n```php\n#[Dto(throwOnViolation: false)]\n```\n\nIf you don't set any value, the configured value (defined in the bundle's configuration file) will be used.\n\n## Events\n- [PreDtoMappingEvent](/src/Event/PreDtoMappingEvent.php) - dispatched before the mapping is made.\n- [PostDtoMappingEvent](/src/Event/PostDtoMappingEvent.php) - dispatched once the mapping is made.\n- [PreDtoValidationEvent](/src/Event/PreDtoValidationEvent.php) - dispatched before the validation is made (if the validation is enabled).\n- [PostDtoValidationEvent](/src/Event/PostDtoValidationEvent.php) - dispatched once the validation is made (if the validation is enabled).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartyuum%2Frequest-dto-mapper-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartyuum%2Frequest-dto-mapper-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartyuum%2Frequest-dto-mapper-bundle/lists"}