Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Dto Bundle Laravel Package

bigyohann/symfony-dto-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require bigyohann/symfony-dto-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Bigyohann\DtoBundle\BigyohannDtoBundle::class => ['all' => true],
    ];
    
  2. First DTO Class: Extend Bigyohann\DtoBundle\Dto\Dto and define private properties with getters:

    use Bigyohann\DtoBundle\Dto\Dto;
    
    class UserDto extends Dto {
        private ?string $name;
    
        public function getName(): ?string { return $this->name; }
    }
    
  3. First Use Case: Convert an array to DTO in a controller:

    use Bigyohann\DtoBundle\Dto\Dto;
    
    public function show(Request $request, Dto $dto): Response {
        $userData = ['name' => 'John'];
        $userDto = $dto->convert($userData); // Auto-maps properties
        return new Response($userDto->getName());
    }
    

Implementation Patterns

Core Workflow

  1. DTO Design:

    • Extend Dto for auto-conversion or DtoInterface for manual control.
    • Use #[ConvertProperty] to opt-in/out of auto-mapping.
    • Example:
      #[ConvertProperty(shouldConvertAutomatically: false)]
      private ?int $id;
      
  2. Controller Integration:

    • Inject Dto service (auto-registered) or create custom DTOs.
    • Convert request data:
      $dto = $this->dtoConverter->convert($request->all(), UserDto::class);
      
  3. Validation: Leverage Symfony’s constraints (e.g., #[Type], #[Length]) directly on DTO properties.

  4. Service Layer: Use DTOs for API responses or form handling:

    public function getUser(User $user): UserDto {
        return (new UserDto())->convert($user->toArray());
    }
    

Advanced Patterns

  • Nested DTOs: Auto-conversion works recursively if nested objects are DTOs.
  • Partial Updates: Use convert() with a subset of properties:
    $dto->convert(['name' => 'Jane']); // Only updates `name`
    
  • Custom Mappers: Override convert() for complex logic:
    public function convert(array $data): self {
        $this->name = strtoupper($data['name'] ?? '');
        return $this;
    }
    

Gotchas and Tips

Pitfalls

  1. Property Visibility:

    • Properties must be private for auto-conversion to work.
    • Getters must exist (no magic methods).
  2. Attribute Conflicts:

    • #[ConvertProperty] overrides default behavior. Omit it to disable auto-conversion for a property.
  3. Circular References:

    • Auto-conversion fails if DTOs reference each other circularly (e.g., UserDto has AddressDto, which has UserDto).
  4. Type Safety:

    • The bundle doesn’t enforce type hints in convert(). Validate manually or use Symfony’s #[Type] constraint.

Debugging

  • Missing Properties: Check for typos in property names or missing getters.
  • Auto-Conversion Issues: Enable debug mode and inspect the convert() method’s input/output.
  • Bundle Not Loaded: Verify BigyohannDtoBundle is in config/bundles.php and composer.json autoloads the Bigyohann\DtoBundle namespace.

Tips

  1. Exclude Sensitive Data: Use shouldConvertAutomatically: false for passwords or tokens:

    #[ConvertProperty(shouldConvertAutomatically: false)]
    private ?string $apiToken;
    
  2. Custom Conversion Logic: Extend Dto and override convert():

    public function convert(array $data): self {
        $data['name'] = ucfirst($data['name']);
        return parent::convert($data);
    }
    
  3. Performance: Reuse DTO instances instead of creating new ones:

    $dto = new UserDto();
    $dto->convert($data); // Reuse instead of `new UserDto()->convert($data)`
    
  4. Testing: Mock Dto in tests to isolate logic:

    $dto = $this->createMock(Dto::class);
    $dto->method('convert')->willReturn($dto);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui