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 Event2{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_id2 3$event->customer_id; // = snowflake_id()
If you wish to disable autofill for some reason, you may set it to false
in your attributes.