Limpe o código php com DTO

Este é meu primeiro artigo, então prepare-se para pegar as pedras.





Ao escrever um novo método ou serviço, tentamos abstraí-lo tanto quanto possível das dependências externas para que a nova funcionalidade implemente apenas a lógica estabelecida para ele. Na verdade, isso é o que nos diz um dos princípios SOLID - o princípio da responsabilidade única .





Constantemente encontro um código onde se um método tem mais de dois argumentos de entrada, um condicional (array $ args) é adicionado, o que implica a implementação de uma verificação para a presença de uma chave, ou se está ausente, e então a probabilidade que o método pode ser pintado em tempo de execução aumenta





Talvez, tal abordagem em PHP tenha se desenvolvido historicamente, devido à falta de tipagem forte e OOP. Afinal, para mim, somente a partir da versão 7 foi possível implementar mais ou menos a digitação + OOP, usando strict_types e type hinting.





Além disso, a chamada de tais métodos pode ser acompanhada por uma descrição do array que passaremos. Ou algum tipo de array com lixo é passado e o método simplesmente pega as chaves de que precisa. Por exemplo, um serviço para criar um usuário:





$userService->create([         
    'name' => $object->name,         
    'phone' => $object->phone,         
    'email' => $object->email,     
]);
      
      



, DTO’. DTO , , . . , , , .





DTO, , . . , , , , .





, .





ClassTransformer

. . , . Laravel :





class UserController extends Controller {
	public function __construct(
      private UserService $userService,
	) {}

	public function createUser(CreateUserRequest $request)
	{
      $dto = ClassTransformer::transform(CreateUserDTO::class, $request);
      $user = $this->userService->create($dto);
      return response(UserResources::make($user));
	}
}
      
      



class CreateUserDTO
{
    public string $name;
    public string $email;
    public string $phone;
}
      
      



: name, phone email. , , , . . transform , object, .  





. , DTO, :





class CreateUserDTO
{
    public string $name;
    public string $email;
    public string $phone;
    
    public static function transform(mixed $args):CreateUserDTO
    {
        $dto = new self();
        $dto->name = $args['fullName'];
        $dto->email = $args['mail'];
        $dto->phone = $args['phone'];
        return $dto;
    }
}
      
      



, , . ? , PHPDoc . , :





class PurchaseDTO
{
    /** @var array<\DTO\ProductDTO> $products Product list */
    public array $products;
    
    /** @var \DTO\UserDTO $user */
    public UserDTO $user;
}
      
      



, . .





, .. . alias , .





?









  • ,









  • ,





  • IDE .





, . Spatie - https://github.com/spatie/data-transfer-object





DTO, DTO, , . , new DTO() .





, , NestJS - plainToClass. , , . ORM ( ), :)





Roadmap

  • Implemente o método afterTransform que será chamado depois que o DTO for inicializado. Isso permitirá que você personalize o elenco de forma mais flexível para a classe. No momento, se as chaves de entrada forem diferentes dos DTOs internos, você mesmo precisa descrever o método de transformação. E se dos 20 parâmetros apenas um tiver uma chave diferente, teremos que descrever a conversão de todos os 20. E com o método afterTransform, podemos personalizar a conversão apenas do parâmetro de que precisamos, e todo o resto será processado por o pacote.





  • Suporte a atributos PHP 8





Isso é tudo.








All Articles