Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto-filling DTOs #98

Closed
wants to merge 2 commits into from
Closed

Auto-filling DTOs #98

wants to merge 2 commits into from

Conversation

sanderdlm
Copy link

@sanderdlm sanderdlm commented Feb 9, 2022

DTOs are useful, but in large projects you end up having to write a lot of boilerplate code to simply pass data from Entity -> DTO and back from DTO -> entity. This PR introduces a new BaseDataTransferObject, which has a "magic" constructor that populates all public properties of a DTO with the matching value it can find if an object is passed to the constructor.

Address DTO

<?php

namespace App\DataTransferObject\Common;

use App\DataTransferObject\BaseDataTransferObject;
use App\Enum\Province;
use Symfony\Component\Validator\Constraints as Assert;

class AddressDataTransferObject extends BaseDataTransferObject
{
    #[Assert\NotBlank]
    public ?string $street = null;

    #[Assert\NotBlank]
    public ?string $number = null;

    #[Assert\NotBlank]
    public ?string $zipCode = null;

    #[Assert\NotBlank]
    public ?string $city = null;

    public Province $province = Province::EastFlanders;

    // NO constructor, uses the parent constructor from BaseDTO
}
<?php

// If nothing is passed to the constructor, nothing gets populated
$createAddress = new createAddress();

// If an entity is passed, the matching properties will be populated
$addressDTO = new AddressDataTransferObject($address);

For example `public string $street` will be be filled from `$address->getStreet()`

// If a message extends from the addressDTO, it will also work
$updateAddress = new UpdateAddress($address);

// If one of the properties in the DTO is also a DTO, it will work recursively

This will save exactly 3.5 minutes for every new DTO that we use 馃槃

Sander De la Marche added 2 commits February 9, 2022 16:54
This iteration will handle recursion, so nested DTOs will
not be a problem anymore.

It also works with the constructor instead of the static
 `from` method call. The only downside to this approach is
that the source objetc that is passed to the DTO isn't
properly type-hinted when you fetch it using the getSource
method. You need to provide an inline @var docblock before
your IDE will autocomplete it and PHPStan will accept it.
@sanderdlm sanderdlm changed the title WIP: Draft a base DTO with a magic 'from' method Auto-filling DTOs Feb 16, 2022
@sanderdlm
Copy link
Author

Deze PR is niet meer nodig. Heb er een bundle van gemaakt: https://github.com/dreadnip/smart-dto-bundle, met ook een attribuut. Op die manier is zowel het invoeren van data in het DTO, als het uitlezen naar een entity geautomatiseerd.

@sanderdlm sanderdlm closed this Feb 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant