Limpiar el código php con DTO

Este es mi primer artículo, así que prepárate para atrapar las piedras.





Al escribir un nuevo método o servicio, tratamos de abstraerlo tanto como sea posible de las dependencias externas para que la nueva funcionalidad implemente solo la lógica establecida para él. De hecho, esto es lo que nos dice uno de los principios SOLID : el principio de responsabilidad única .





Constantemente me encuentro con un código en el que si un método tiene más de dos argumentos de entrada, se agrega un condicional (matriz $ args), lo que implica la implementación de una verificación de la presencia de una clave, o está ausente, y luego la probabilidad que el método se puede pintar sobre en tiempo de ejecución aumenta.





Quizás, tal enfoque en PHP se ha desarrollado históricamente, debido a la falta de tipado fuerte y tal POO. Después de todo, en lo que a mí respecta, solo a partir de la versión 7 fue posible implementar más o menos typing + OOP, usando strict_types y type hinting.





Además, la llamada a dichos métodos puede ir acompañada de una descripción de la matriz que pasaremos. O se pasa algún tipo de matriz con basura, y el método simplemente toma las claves que necesita. Por ejemplo, un servicio para crear un usuario:





$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 el método afterTransform que se llamará después de que se inicialice el DTO. Esto te permitirá personalizar de forma más flexible el casting para la clase. Por el momento, si las claves de entrada son diferentes de los DTO internos, debe describir el método de transformación usted mismo. Y si de 20 parámetros solo uno tiene una clave diferente, tendremos que describir la conversión de los 20. Y con el método afterTransform, podemos personalizar la conversión de solo el parámetro que necesitamos, y todo el resto será procesado por el paquete.





  • Compatibilidad con atributos de PHP 8





Eso es todo.








All Articles