Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony 6.3 / Post Request with MapRequestPayload

I would like to use the MapRequestPayload attribute to create an entity from the POST request data.

I then validate this and then save it.

This works very well so far, but how do you deal with data from a select?

{
    "name": "test",
    "firstname": "test",
    "company_id": 486
}

compay_id is a select in a frontend.

This is of course ignored when assigning, which is ok because it shouldn't be created, but the relationship should be saved.

My approach would now be the following, but it doesn't work because the MapEntity attribute refers to the Request Query.

    public function add(
        #[MapRequestPayload] Person $person,
        #[MapEntity(id: 'company_id')] Company $company
    ): JsonResponse
    {
        $person->setCompany($company);
    }

Do you know a way to do that?

like image 518
Creator Avatar asked Feb 25 '26 15:02

Creator


1 Answers

I had a similar problem, and the solution can change accordingly with your needs

Remember that your payload does not represent an actual entity of your application, it represent a DTO

So one solution is to have a separete DTO:

<?php
    
declare(strict_types=1);

namespace App\Dto;

use Symfony\Component\Validator\Constraints as Assert;

#[Assert\Cascade]
class MyDTO {
    #[Assert\NotNull]
    public string $name;
    #[Assert\NotNull]
    public string $surname;
    #[Assert\NotNull]
    public int $company_id;         
}

and map the DTO into your entities in the controller.

The other solution is to change some logic: why are you adding a company id in the user and you require to specify the user data in the payload?

I guess: I have a user and I need to add a company -> I have to implement a post request with /user/{id}/addCompany and I can select the user (with a repo) and then adding the company like this:

#[Route('user/{id}/add-company', name: 'user-add-company', methods: ['POST'])]
public function update(
    int $id,
    #[MapRequestPayload]
    Company $company,
): Response {
    $user = $userRepo->getById($id);
    
    $user->setCompany($company);


    return $this->json('OK');
}

Or I need to create a user AND the company together:

#[Route('/user-with-company', name: 'user-with-company', methods: ['POST'])]
public function createUserWithCompany(
    #[MapRequestPayload]
    User $user;
): Response {
    $user = $userRepo->create($user);

    return $this->json('OK');
}

And your User object should contain a property company. In this case you should modify your incoming payload:

{
    name:"John",
    surname:"Doe",
    company: {
        id: 1,
        name: 'Acme"
    }
}
like image 181
Web-Fu Avatar answered Feb 27 '26 05:02

Web-Fu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!