GlosarioArquitectura

¿Qué es una Action?

Una Action en Laravel es una clase dedicada a ejecutar una única operación de negocio, encapsulando la lógica en un lugar reutilizable e independiente de controladores, comandos o jobs.

Actions

Las Actions son clases que encapsulan una única operación de negocio siguiendo el principio de responsabilidad única (SRP). Aunque Laravel no incluye un estándar oficial para crearlas, es un patrón muy extendido en la comunidad para organizar la lógica de negocio fuera de los controladores.

Estructura básica

Una Action típica tiene un único método público handle:

class CreateInvoiceAction
{
    public function __construct(
        private readonly TaxCalculator $taxCalculator,
        private readonly InvoiceRepository $invoices,
    ) {}

    public function handle(User $user, array $items): Invoice
    {
        $subtotal = collect($items)->sum('price');
        $tax = $this->taxCalculator->calculate($subtotal);

        return $this->invoices->create([
            'user_id' => $user->id,
            'subtotal' => $subtotal,
            'tax' => $tax,
            'total' => $subtotal + $tax,
            'items' => $items,
        ]);
    }
}

La gran ventaja es que la misma Action se puede reutilizar desde un controlador, un comando Artisan, un Job o un test sin duplicar lógica.

Laractions

El paquete Laractions, creado por la comunidad española, proporciona una arquitectura completa para trabajar con Actions en Laravel. Se instala con composer require edulazaro/laractions y permite generar Actions con Artisan:

php artisan make:action SendEmailAction

Las Actions generadas extienden la clase base Action y se ejecutan con el patrón create()->run():

use EduLazaro\Laractions\Action;

class SendEmailAction extends Action
{
    public function handle(string $email, string $subject, string $message)
    {
        // Lógica de envío
    }
}

// Ejecutar la action
SendEmailAction::create()->run('user@example.com', 'Bienvenido', 'Hola');

También soporta Actions vinculadas a modelos usando el trait HasActions:

class User extends Model
{
    use HasActions;

    protected array $actions = [
        'send_email' => SendEmailAction::class,
    ];
}

// Ejecutar desde el modelo
$user->action('send_email')->run('user@example.com', 'Bienvenido', 'Hola');

Entre sus funcionalidades destacan la ejecución asíncrona mediante colas (->queue('high')->delay(10)->dispatch()), trazabilidad de acciones con el método ->trace(), soporte para actores con el trait IsActor, y un sistema de mocking para tests.

Cuándo usar Actions

Las Actions son ideales cuando la lógica de negocio crece más allá de unas pocas líneas en el controlador, cuando necesitas reutilizar la misma operación en varios puntos de la aplicación, o cuando quieres que tu código sea más fácil de testear. Son una alternativa ligera a los Service classes cuando cada operación es lo bastante independiente como para vivir en su propia clase.