LARAVEL OBSERVER VS LISTENER: ¿CUÁNDO USAR CADA UNO?
En Laravel, tanto los Observers como los Listeners son herramientas poderosas para implementar lógica reactiva. Sin embargo, tienen propósitos diferentes y usar uno en lugar del otro puede generar código difícil de mantener o arquitecturas confusas.¿Qué es un Observer?
Un Observer está diseñado para reaccionar a los cambios en el ciclo de vida de un solo modelo Eloquent. Se activa automáticamente cuando ocurre un evento en el modelo: "created", "updated", "deleted", "saved", "restored", etc. Tanto los Observers como los Listeners son excelentes, pero tienen un propósito distinto. Usar la herramienta correcta en el momento adecuado es lo que diferencia un código mantenible y escalable de uno que se vuelve una bola de nieve.Casos de uso
- Crear logs de auditoría
- Invalidar caché relacionado con el modelo
- Sincronizar datos relacionados (ej. actualizar contadores)
- Mantener lógica estrechamente relacionada con el modelo
Ejemplo
// app/Observers/UserObserver.php
class UserObserver
{
public function created(User $user): void
{
AuditLog::create([
'user_id' => $user->id,
'event' => 'created',
]);
}
public function updated(User $user): void
{
// Invalidar caché, recalcular algo, etc.
}
}
¿Qué es un Listener?
Un Listener reacciona a Eventos de dominio o eventos de negocio que el programador despacha. Es parte del patrón Event-Driven Architecture y es mucho más flexible para lógica de aplicación.Casos de uso
- Enviar emails de bienvenida
- Notificaciones push
- Integraciones con terceros (Slack, Stripe Webhooks, etc.)
- Tracking de analytics
- Workflows asíncronos
- Cualquier acción que represente un evento de negocio
Ejemplo
// Evento
event(new UserRegistered($user));
// Listener
class SendWelcomeEmail implements ShouldQueue
{
public function handle(UserRegistered $event): void
{
Mail::to($event->user->email)
->send(new WelcomeEmail($event->user));
}
}
Mejores Prácticas
- Mantener los Observers solo con lógica relacionada directamente con el modelo.
- Usar Listeners para tareas pesadas como correos, notificaciones, integraciones externas.
- Aprovechar Queued Listeners e implementar ShouldQueue siempre que sea posible.
- Nombrar bien los evento como "UserRegistered", "OrderShipped", "PaymentFailed", etc.
- Usar Event Discovery ya que reduce la configuración manual.
- Type Safety con tipado fuerte en eventos y listener.
Si la lógica está atada al modelo → Observer.
Si la lógica representa una acción de negocio → Evento + Listener.