Event Bus

1 min read · last updated at

Web applications are eventful by nature. At some point, it will need to handle an incoming request and generate a response. There we have two important events, that components of your application might want to know about.

The component responsible for distributing events to components that want to know about them is usually called Event Bus.

How It works

Defining The Payload

Events are usually simple classes like the ones below:

Events are plain PHP classes, that optionally use the Dispatchable trait.

app/Events/NewUser.php
namespace App\Events;
class NewUser
{
// (optional) Makes it easier to dispatch this event
use \Illuminate\Foundation\Events\Dispatchable;
public function __construct(public \App\Models\User $user)
{
}
}

Events extend the ApplicationEvent class:

src/com/example/user/NewUser.java
public class NewUser extends ApplicationEvent {
private final User user;
public NewUser(Object source, User user) {
super(source);
this.user = user;
}
public User getUser() {
return this.user;
}
}

Dispatch An Event

These event classes can then be published or dispatched onto the event bus. See the examples below for how different frameworks implement this.

An event can be dispatched either using

NewUser::dispatch($user);

if your event class uses the Dispatchable-trait mentioned earlier. Otherwise use the Event alias:

Event::dispatch(new NewUser($user));

which could be more convenient for autocompletion and static analysis, since it uses less magic to resolve the constructor arguments.

Spring’s ApplicationEventPublisher is responsible for publishing events and can be injected into any class that implements the ApplicationEventPublisherAware interface:

src/com/example/user/UserService.java
package com.example.user;
class UserService implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
private final UserRepository repository;
public UserService(private final UserRepository repository) {
this.repository = repository;
}
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void register(String email, String password) {
var user = new User(email, password);
this.repository.persist(user);
// Here is the interesting part that actually publishes the event
this.publisher.publishEvent(this, new NewUser(user));
}
}

Handle An Event

To handle events, your application defines and registers listeners. When dispatching an event, the event bus iterates through all listeners interested in that type of event and executes their logic:

A listener is a class with a __invoke or handle method like this one:

app/Listeners/SendWelcomeEmail.php
namespace App\Listeners;
class SendWelcomeEmail
{
public function __invoke(\App\Events\NewUser $event): void
{
// ...
}
}

Make sure to specify the parameter type of the event, since Laravel uses this information to detect which listener gets called for a event. Such a class can be created using the artisan tool:

php artisan make:listener SendPodcastNotification --event=PodcastProcessed

Instead of explicitly registering listeners, we can

app/Providers/EventServiceProvider.php
<?php
namespace App\Providers;
class EventServiceProvider extends \Illuminate\Foundation\Support\Providers\EventServiceProvider
{
/**
* The event to listener mappings for the application.
*
* @var array<class-string, array<int, class-string>>
*/
protected $listen = [
\Illuminate\Auth\Events\Registered::class => [
\Illuminate\Auth\Listeners\SendEmailVerificationNotification::class,
],
];
// ...
}

Learn more at https://laravel.com/docs/events.

Listeners are beans that implement the ApplicationListener:

src/com/example/user/NewUserListener.java
public class NewUserListener implements ApplicationListener<NewUser> {
public void onApplicationEvent(NewUser event) {
// Send a welcome email to the user
}
}

Learn more at https://docs.spring.io/spring-framework/reference/core/beans/context-introduction.html#context-functionality-events

Job Queues

Database Transactions