Verbs

Event Lifecycle

Verbs Event Lifecycle Diagram

Firing Events

When you fire a Verbs event for the first time, it passes through three major phases (firing, fired, and committed) — each with its own individual steps.

“Firing” Phase

Before your event can be applied, we must make sure it has all the data necessary, and check to see if it's valid. The entire Firing phase only happens when an event is first fired (not when events are re-applied to State or replayed).

__construct()

The event constructor is only called once when the event is first fired. It will not be called again if the event is ever replayed or re-applied to State.

By the time the constructor has finished, the event should have all the data it needs for the rest of the event lifecycle (you shouldn't do any data retrieval after this point).

Authorize

Use the authorize method on your Event to ensure that the current user is allowed to fire it. The authorize method behaves exactly the same as Laravel form requests.

Validate

Use the validate hook to ensure that an event can be fired given the current State(s). Any method on your event that starts with validate is considered a validation method, and validation may run for each state the event is firing on (based on what you type-hint).

For example, an event that fires on two States might have two validation methods:

1class UserJoinedTeam
2{
3 // ...
4 
5 public function validateUser(UserState $user)
6 {
7 $this->assert($user->can_join_teams, 'This user must upgrade before joining a team.');
8 }
9 
10 public function validateTeam(TeamState $team)
11 {
12 $this->assert($team->seats_available > 0, 'This team does not have any more seats available.');
13 }
14}

“Fired” Phase

Before your event is saved to the database, and any side effects are triggered, it needs to apply to any state. This lets you update your "event world" before the rest of your application is impacted.

Apply

Use the apply hook to update the state for the given event. Any method on your event that starts with apply is considered an apply method, and may be called for each state the event is firing on (based on what you type-hint). Apply hooks happen immediately after the event is fired, and also any time that state needs to be re-built from existing events (i.e. if your snapshots are deleted for some reason).

For example, an event that fires on two States might have two apply methods:

1class UserJoinedTeam
2{
3 // ...
4 
5 public function applyToUser(UserState $user)
6 {
7 $user->team_id = $this->team_id;
8 }
9 
10 public function applyToTeam(TeamState $team)
11 {
12 $team->team_seats--;
13 }
14}

Fired

Use the fired hook for anything that needs to happen after the event has been fired, but before it's handled. This is typically used for firing additional events.

“Committed” Phase

Once the event has been fired and stored to the database (committed), it's now safe to trigger side effects.

Handle

Use the handle hook to perform actions based on your event. This is often writing to the database (sometimes called a "projection"). You can read more about the handle hook in the Events docs.

Replaying Events

When you replay a Verbs event, it does not pass through these same phases. It's best to think of replays as something that happens later to the same event. During replay, only two lifecycle hooks are called:

  1. Apply
  2. Handle

If you do not want your handle method to re-run during replay, you can either use the Once attribute, or use the Verbs::unlessReplaying helper.