Verbs

IDs

By default, Verbs uses 64-bit integer IDs called "Snowflakes."

Globally Unique Ids

We do this because an event-sourcing system needs globablly-unique IDs to run well. Replaying events is a powerful feature, but does not pair well with standard auto-incrementing IDs. Unique IDs help us both minimize collisions, so that each event is executed with fidelity, and maximize interoperability.

We recommend Snowflakes because they are sortable, time-based, and are integers. You may also use ULIDs or UUIDs instead; this can be configured in config/verbs.php. However, they each introduce some complexity. Both are strings, and UUIDs are not sortable.

Snowflakes in Verbs

Verbs uses glhd/bits under the hood, and you can use it too. Bits makes it easy to use Snowflakes in Laravel. If you're planning to run an app on more than one app server, check out Bits configuration.

A helper method you can use to generate a snowflake right out of the box: snowflake_id()

For models that you're going to manage via events, pull in the HasSnowflakes trait:

1use Glhd\Bits\Database\HasSnowflakes;
2use Glhd\Bits\Snowflake;
3 
4class JobApplication extends Model
5{
6 use HasSnowflakes; // Add this to your model
7 
8 // Any attribute can be cast to a `Snowflake` (or `Sonyflake`)
9 protected $casts = [
10 'id' => Snowflake::class,
11 ];
12}

Bits also provides helpers for your migrations:

1/**
2 * Run the migrations.
3 */
4public function up(): void
5{
6 Schema::create('job_applications', function (Blueprint $table) {
7 $table->snowflakeId();
8 $table->snowflake('user_id')->index();
9 $table->foreign('user_id')->references('id')->on('users');
10 // ...
11 });
12}

The snowflakeId() method creates a new primary key column with a default name of 'id'. The snowflake() method adds a regular snowflake column which is ideal for creating foreign keys.

Automatically generate snowflake ids

Verbs allows for snowflake_id auto-generation by default when using most of our attributes. By setting your event's state_id property to null--

1class CustomerBeganTrial extends Event
2{
3 #[StateId(CustomerState::class)]
4 public ?int $customer_id = null;
5}

--and setting no id value when you fire your event, you allow Verbs' autofill default to provide a snowflake_id() for you.

1$event = CustomerBeganTrial::fire() // no set customer_id
2 
3$event->customer_id; // = snowflake_id()

If you wish to disable autofill for some reason, you may set it to false in your attributes.