2. Herramientas de generación de código
2.1. Introducción al comando "artesano"
El framework incluye una herramienta de línea de comandos llamada "artesano" que facilita la creación de código repetitivo y estructurado. Esta herramienta te ahorra tiempo y reduce errores al generar automáticamente archivos con una estructura consistente.
La herramienta "artesano" se encuentra en la raíz del proyecto y se ejecuta con PHP:
php artesano [comando] [argumentos]
Los principales comandos disponibles son:
create-legacy-infrastructure(alias:cli): Para crear conexiones con sistemas legacy de Quartupcreate-domain(alias:cd): Para crear dominios de API completos
Estos comandos generan código siguiendo las convenciones del framework, manteniendo la coherencia en todo el proyecto.
2.2. Creando una infraestructura con CLI (create-legacy-infrastructure)
El comando create-legacy-infrastructure genera la capa de acceso a datos para interactuar con tablas del sistema legacy Quartup.
2.2.1. Parámetros y opciones
La sintaxis del comando es:
php artesano create-legacy-infrastructure [modulo] [recurso] [tabla]
Donde:
[modulo]: Es el módulo de Quartup (por ejemplo: p-maes, p-pos, p-vtas)[recurso]: Es el nombre amigable que quieres darle al recurso (por ejemplo: productos, clientes, ventas)[tabla]: Es el nombre real de la tabla en Quartup (por ejemplo: maesarti, poscli, venfaccab)
2.2.2. Archivos generados y su propósito
El comando genera dos archivos esenciales:
-
Model:
src/Infrastructures/Legacy/{ModuloCamel}/{TablaCamel}{RecursoCamel}/{TablaCamel}{RecursoCamel}Model.phpEste archivo define la conexión con la tabla de Quartup y contiene:
- La referencia a la tabla
- Configuraciones específicas para la conexión
namespace Infrastructures\Legacy\PMaes\MaesartiProductos;
use App\Base\DB\BaseModelTree as Model;
class MaesartiProductosModel extends Model
{
public $table = 'maesarti';
public function __construct()
{
parent::__construct();
}
} -
Repository:
src/Infrastructures/Legacy/{ModuloCamel}/{TablaCamel}{RecursoCamel}/{TablaCamel}{RecursoCamel}Repository.phpEste archivo proporciona métodos para realizar operaciones en la tabla:
- Consultas personalizadas
- Operaciones CRUD básicas
- Métodos específicos para casos de uso comunes
namespace Infrastructures\Legacy\PMaes\MaesartiProductos;
use App\Base\Repository;
class MaesartiProductosRepository extends Repository
{
protected $model;
public function __construct(MaesartiProductosModel $model)
{
$this->model = $model;
}
}
2.2.3. Ejemplo paso a paso
Vamos a crear una infraestructura para acceder a clientes en el sistema Quartup:
-
Ejecutamos el comando:
php artesano create-legacy-infrastructure p-pos clientes poscli -
Esto generará:
src/Infrastructures/Legacy/PPos/PoscliClientes/PoscliClientesModel.phpsrc/Infrastructures/Legacy/PPos/PoscliClientes/PoscliClientesRepository.php
-
Los archivos generados están listos para usar y no requieren modificaciones adicionales.
-
Podemos extender el repositorio si necesitamos consultas específicas:
// Añadimos un método personalizado al repositorio
public function findByEmail($email)
{
return $this->selectOne(['email' => $email]);
}
2.3. Creando un dominio con CD (create-domain)
El comando create-domain genera una API completa para un recurso, incluyendo controlador, servicio, rutas y DTOs.
2.3.1. Parámetros y opciones
La sintaxis del comando es:
php artesano create-domain [dominio] [infraestructura] [modulo]
Donde:
[dominio]: Nombre del dominio en singular (por ejemplo: Product, Customer, Order)[infraestructura]: Referencia a la infraestructura legacy en formatoModuloCamel_TablaCamelRecursoCamel(por ejemplo:PMaes_MaesartiProductos)[modulo](opcional): Si quieres crear el dominio dentro de un módulo específico
2.3.2. Archivos generados y su propósito
El comando genera varios archivos que conforman un CRUD completo:
-
Controller:
src/ApiLayer/Domains/{Dominio}s/{Dominio}sController.phpManeja las peticiones HTTP y aplica validaciones:
class ProductsController extends DomainController
{
protected $productsService;
public function __construct(ProductsService $service)
{
parent::__construct($service);
// Definición de validaciones
$this->validations = [
'headers' => [],
'body' => [],
];
}
} -
Service:
src/ApiLayer/Domains/{Dominio}s/{Dominio}sService.phpContiene la lógica de negocio:
class ProductsService extends DomainService
{
protected $maesartiProductosRepository;
protected $resMaesartiProductosDTO;
protected $reqMaesartiProductosDTO;
public function __construct(
MaesartiProductosRepository $maesartiProductosRepository,
ResMaesartiProductosDTO $resMaesartiProductosDTO,
ReqMaesartiProductosDTO $reqMaesartiProductosDTO
) {
$this->maesartiProductosRepository = $maesartiProductosRepository;
$this->resMaesartiProductosDTO = $resMaesartiProductosDTO;
$this->reqMaesartiProductosDTO = $reqMaesartiProductosDTO;
$this->maesartiProductosRepository->selectable(ResMaesartiProductosDTO::$selectables);
}
// Métodos de servicio para index, selectById, store, update, delete
} -
Routes:
src/ApiLayer/Domains/{Dominio}s/{Dominio}sRoutes.phpDefine las rutas RESTful:
$middlewares = ['before' => [AuthMiddleware::class]];
Route::group(ProductsController::class, function () use ($middlewares) {
Route::get('products/', 'index', $middlewares);
Route::get('products/:id', 'show', $middlewares);
Route::post('products/', 'store', $middlewares);
Route::put('products/:id', 'update', $middlewares);
Route::delete('products/:id', 'delete', $middlewares);
}); -
DTOs:
- Request DTO para mapeo de entradas:
src/ApiLayer/Domains/{Dominio}s/DTOs/Req{Infraestructura}DTO.php - Response DTO para mapeo de salidas:
src/ApiLayer/Domains/{Dominio}s/DTOs/Res{Infraestructura}DTO.php
// DTO de respuesta
class ResMaesartiProductosDTO extends ResDto
{
public static $selectables = [
'nombre',
'cod_articulo',
];
// Propiedades y métodos
}
// DTO de petición
class ReqMaesartiProductosDTO extends ReqDto implements InterfaceReqDto
{
protected $mapFilters = [
'name' => 'nombre',
];
// Métodos para transformación de datos
} - Request DTO para mapeo de entradas:
2.3.3. Ejemplo paso a paso
Vamos a crear un dominio para gestionar clientes:
-
Primero creamos la infraestructura (si no la tenemos ya):
php artesano create-legacy-infrastructure p-pos clientes poscli -
Luego creamos el dominio:
php artesano create-domain Customer PPos_PoscliClientes -
Esto generará:
src/ApiLayer/Domains/Customers/CustomersController.phpsrc/ApiLayer/Domains/Customers/CustomersService.phpsrc/ApiLayer/Domains/Customers/CustomersRoutes.phpsrc/ApiLayer/Domains/Customers/DTOs/ReqPoscliClientesDTO.phpsrc/ApiLayer/Domains/Customers/DTOs/ResPoscliClientesDTO.php
-
Editamos el DTO de respuesta para definir los campos a mostrar:
// src/ApiLayer/Domains/Customers/DTOs/ResPoscliClientesDTO.php
public static $selectables = [
'nombre',
'apellidos',
'email',
'telefono',
'direccion'
];
public function toArray(): array
{
return [
'id' => (string) $this->id,
'fullName' => $this->nombre . ' ' . $this->apellidos,
'email' => $this->email,
'phone' => $this->telefono,
'address' => $this->direccion
];
} -
Editamos el DTO de petición para mapear los campos:
// src/ApiLayer/Domains/Customers/DTOs/ReqPoscliClientesDTO.php
protected $mapFilters = [
'fullName' => 'nombre',
'email' => 'email',
'phone' => 'telefono',
'address' => 'direccion'
];
public function handle(array $data): InterfaceReqDto
{
// Separar el nombre completo en nombre y apellidos
$fullNameParts = explode(' ', $data['fullName'] ?? '', 2);
$this->nombre = $fullNameParts[0] ?? null;
$this->apellidos = $fullNameParts[1] ?? null;
$this->email = $data['email'] ?? null;
$this->telefono = $data['phone'] ?? null;
$this->direccion = $data['address'] ?? null;
return $this;
} -
Añadimos validaciones en el controlador:
// src/ApiLayer/Domains/Customers/CustomersController.php
$this->validations = [
'headers' => ['x-tienda' => 'required|string'],
'body' => [
'fullName' => 'required|string',
'email' => 'required|email',
'phone' => 'required|string',
'address' => 'string'
]
]; -
¡Y ya tenemos un CRUD completo para clientes!
Creación en un módulo específico
Si queremos crear el dominio dentro de un módulo (por ejemplo, en el módulo "Admin"), usamos:
php artesano create-domain Customer PPos_PoscliClientes Admin
Esto generará los archivos en src/ApiLayer/Modules/Admin/Domains/Customers/ y las rutas tendrán el prefijo admin/customers/.
Resumen
Las herramientas de generación de código del framework te permiten crear rápidamente:
- Infraestructuras Legacy: Para conectar con tablas de Quartup
- Dominios: CRUD completos con rutas, controladores, servicios y DTOs
Estos comandos aceleran enormemente el desarrollo, permitiéndote concentrarte en personalizar los DTOs y definir validaciones, mientras que el framework se encarga de todo el código repetitivo y estructural.
La combinación de estos dos comandos proporciona una forma poderosa y eficiente de construir APIs completas con un mínimo esfuerzo, siguiendo las mejores prácticas y manteniendo la coherencia en todo el proyecto.