You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Symfony provides attributes like #[MapRequestPayload], #[MapQueryParameter], and #[MapUploadedFile] to conveniently map request data to typed objects (DTOs) in controller actions. These attributes are resolved using Symfony’s argument value resolvers and provide a powerful declarative experience — including automatic validation, format handling, and integration with the Serializer and Validator components.
However, this functionality is currently limited to controller arguments. In many real-world applications, developers frequently need to map and validate request data outside of controllers — for example:
In custom authenticators
In event listeners or middleware
In reusable services handling Request objects
Currently, developers must reimplement mapping and validation logic manually in these contexts, leading to duplicated effort, inconsistent behavior, and poor DX (developer experience).
Goal
Enable the same mapping and validation behavior available via #[MapRequestPayload], #[MapQueryParameter], and #[MapUploadedFile] in any Symfony service, not just controller actions.
Proposal
Extract the core logic of the existing attribute-based mapping system into reusable internal services:
PayloadMapper — handles deserialization of JSON/XML/etc. from the request body
QueryParameterMapper — maps query string data into DTOs
UploadedFileMapper — extracts and maps uploaded files
These will encapsulate the transformation logic without coupling to the controller resolver system.
Introduce a high-level public API: RequestDataMapper
This service:
Combines mapping and validation
Uses the mappers above
Reproduces the exact behavior of controller argument resolution
Throws ValidationFailedException on constraint violations
Designed for use in custom authenticators, listeners, services, etc.
No changes to controller attribute behavior. The #[MapRequestPayload] and other attributes will continue to use the current value resolver mechanism.
Internally, these resolvers will be refactored to delegate to the new mappers, avoiding duplicated logic and ensuring consistency.
Developers can inject RequestDataMapper into any service via autowiring.
Backward Compatibility
This change is fully backward-compatible.
All existing controller attribute behavior remains unchanged.
The new mappers and RequestDataMapper are additive and opt-in.
Implementation Plan
If accepted, I propose to:
Extract existing logic from the controller value resolvers into three private mappers:
PayloadMapper
QueryParameterMapper
UploadedFileMapper
Introduce a new public service RequestDataMapper that:
Uses the above
Handles validation
Mirrors controller behavior
Update the current value resolvers to delegate to the new services
Add functional and unit tests for:
Each mapper individually
Combined RequestDataMapper usage
Exception handling and validation
Update Symfony documentation (if needed) with examples for RequestDataMapper.
Conclusion
This RFC proposes a clean, fully backward-compatible enhancement to Symfony's request handling model. It extracts and elevates the powerful attribute-based mapping logic into reusable, injectable services — aligning with Symfony’s philosophy of modularity and DX excellence.
It closes a common gap experienced by developers working with authenticators, listeners, and service-level request data access.
There is also a PR to introduce ArgumentResolver component: #59794
Imho not a duplicate. This RFC argues that the functionality of mapping requests should not be (just a) part of the argument resolver, but as different components. Those components have nothing to do with argument resolving.
Allowing to call argument resolvers outside of controllers does not solve the architectural problem imho.
There is also a PR to introduce ArgumentResolver component: #59794
Duplicate of #53915 ?
There is also a PR to introduce ArgumentResolver component: #59794
Imho not a duplicate. This RFC argues that the functionality of mapping requests should not be (just a) part of the argument resolver, but as different components. Those components have nothing to do with argument resolving.
Allowing to call argument resolvers outside of controllers does not solve the architectural problem imho.
Thanks for the input! I agree this is not a duplicate of #53915 or #59794. Those focus on making argument resolvers more flexible or reusable, but this RFC proposes a dedicated component for mapping and validating request data independently of argument resolution. The goal is to support use cases like authenticators or event listeners, where simulating controller callables just to deserialize and validate DTOs is awkward. This is about separating concerns and enabling cleaner, more explicit application architecture.
Description
Motivation
Symfony provides attributes like
#[MapRequestPayload]
,#[MapQueryParameter]
, and#[MapUploadedFile]
to conveniently map request data to typed objects (DTOs) in controller actions. These attributes are resolved using Symfony’s argument value resolvers and provide a powerful declarative experience — including automatic validation, format handling, and integration with the Serializer and Validator components.However, this functionality is currently limited to controller arguments. In many real-world applications, developers frequently need to map and validate request data outside of controllers — for example:
Currently, developers must reimplement mapping and validation logic manually in these contexts, leading to duplicated effort, inconsistent behavior, and poor DX (developer experience).
Goal
Enable the same mapping and validation behavior available via
#[MapRequestPayload]
,#[MapQueryParameter]
, and#[MapUploadedFile]
in any Symfony service, not just controller actions.Proposal
Extract the core logic of the existing attribute-based mapping system into reusable internal services:
These will encapsulate the transformation logic without coupling to the controller resolver system.
Introduce a high-level public API: RequestDataMapper
This service:
Example usage:
Design
Low-level mappers (internal services)
These services handle extraction and transformation only. No validation logic.
High-level public service
Integration
Backward Compatibility
Implementation Plan
If accepted, I propose to:
Extract existing logic from the controller value resolvers into three private mappers:
Introduce a new public service RequestDataMapper that:
Update the current value resolvers to delegate to the new services
Add functional and unit tests for:
Update Symfony documentation (if needed) with examples for RequestDataMapper.
Conclusion
This RFC proposes a clean, fully backward-compatible enhancement to Symfony's request handling model. It extracts and elevates the powerful attribute-based mapping logic into reusable, injectable services — aligning with Symfony’s philosophy of modularity and DX excellence.
It closes a common gap experienced by developers working with authenticators, listeners, and service-level request data access.
Example
Use Cases
The text was updated successfully, but these errors were encountered: