Skip to content

#[Map...] is a mess (rfc) #58662

Open
Open
@klkvsk

Description

@klkvsk

Description

Mapping attributes for controller arguments are a mix of different concepts.
#[MapEntity], #[MapDateTime] - are "map to what".
#[MapQueryString], #[MapQueryParameter], #[MapRequestPayload], #[MapUploadedFile] - are "map from where".

Moreover, they can not be combined, as such you can not do

#[MapEntity]
#[MapQueryParameter]
Post $post

Providing a value resolver in most cases would not work either:

#[MapQueryParameter(resolver: EntityValueResolver::class)]
Post $post

The problem is ValueResolvers are hardcoded to check only a single input bag (Entity- and DateTimeValueResolver check only request attributes).

Proposed solution:

  1. Introduce the \Symfony\Component\HttpKernel\Attribute\ValueConsumer base attribute
  2. Introduce a set of ValueConsumer attributes:
    • #[RouteParam], #[QueryParam], #[QueryString], #[BodyParam], #[BodyPayload], #[HeaderParam]
    • can be combined in order to support cases when the value can be sent either in query or post data.
  3. Add optional third param in ValueResolverInterface::resolve:
interface ValueResolverInterface
{
    public function resolve(Request $request, ArgumentMetadata $argument, mixed $value = null): iterable;
}
  1. in \Symfony\Component\HttpKernel\Controller\ArgumentResolver::getArguments() before calling resolvers, run through ValueConsumer attributes defined for argument until one returning a value, then pass this value to resolve().
  2. Update all ValueResolvers to use $value if provided. If not, fallback to their original logic.

Example

#[Route('/posts/cat/{category}/{date?}')]
public function posts(
    #[RouteParam]
    PostCategory $category,

    #[RouteParam('date')]
    #[QueryParam]
    ?\DateTimeInterface $dateFrom,

    #[RouteParam('date')]
    #[QueryParam]
    ?\DateTimeInterface $dateTo,
) {
    // /posts/cat/1/2024-10-25, same as:
    // /posts/cat/1?dateFrom=2024-10-25&dateTo=2024-10-25
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    HttpKernelRFCRFC = Request For Comments (proposals about features that you want to be discussed)Stalled

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions