PATRÓN DE ACCIONES EN LARAVEL

Las Actions en Laravel son un patrón de diseño muy popular para organizar la lógica de negocio de forma limpia, reutilizable y testable. No forman parte del núcleo oficial de Laravel, pero se han convertido en una práctica estándar recomendada por muchos desarrolladores.
Los Actions son clases dedicadas a realizar una única tarea o acción específica del negocio. Siguen el principio Single Responsibility Principle (una clase = una responsabilidad).
Ejemplos típicos:
  • CreateUserAction → crea un usuario, valida datos, envía email de bienvenida, etc.
  • ProcessOrderAction → procesa un pedido completo (actualiza stock, genera factura, envía notificación).
  • SendWelcomeEmailAction → solo envía el email de bienvenida (si quieres máxima granularidad).
  • PublishPostAction → publica un post y maneja todo lo relacionado (tags, notificaciones, etc.).

Estructura de un Action

La mayoría de las Actions se escriben como clases invokables (usando el método mágico "__invoke()") o con un método principal llamado "handle()" o "execute()".Ejemplo básico:

namespace App\Actions\User;

use App\Models\User;
use Illuminate\Support\Facades\Hash;

class CreateUserAction
{
    public function __invoke(array $data): User
    {
        $user = User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);

        // Puedes disparar eventos, jobs, etc.
        event(new UserRegistered($user));

        return $user;
    }
}

//Uso en un controlador
public function store(Request $request, CreateUserAction $action)
{
    $validated = $request->validate([...]);

    $user = $action($validated);  // ¡Se llama como si fuera una función!

    return response()->json($user, 201);
}

//Usando execute
$action = app(CreateUserAction::class);
$user = $action->execute($data);
Para crear actions se puede usar:
  • "lorisleiva/laravel-actions" (permite invocarlas como controladores, jobs, etc. automáticamente).
  • Otros solo usan el patrón manual (crean las clases en app/Actions/ y ya).

¿Por qué usar Actions en vez de meter todo en controllers o services?

Aspecto Controllers / Services gordos Actions
Responsabilidades Muchas (validación + lógica + response) Una sola tarea clara
Tamaño de clase Crece mucho → "God classes" difíciles de leer Pequeñas y enfocadas
Reutilización Difícil (lógica atada a HTTP o a un modelo) Muy alta (se usan en controllers, jobs, commands, listeners...)
Testeo Tests complejos y acoplados Fáciles de unit testear (solo la lógica)
Mantenibilidad Baja cuando el proyecto crece Alta, fácil refactorizar o reemplazar