avatarAdrian Generous

Summarize

Mastering Snowflake in Laravel: A Guide from Installation to Implementation

In my latest article available on Medium, I delved into the topic of Snowflake identifiers in programming and touched on the differences in approach between UUIDs and IDs. I am a big advocate of using Snowflake, especially from the perspective of optimization and sorting results “in time”. Snowflake performs excellently in these aspects. If you want to take a closer look at the topic, I invite you to check out my previous article. However, now I will focus on its implementation in the Laravel application.

Programming in Laravel

Programming daily in Laravel, I was looking for an optimal package that would provide me with the necessary solutions to implement Snowflake in my project. My choice fell on the caneara/snowflake package, available at github.com/caneara/snowflake.

Installation

We install the package standardly through Composer:

composer require caneara/snowflake

The package configuration, described in the README file, allows for very advanced customization, such as setting distributed data nodes or the initial timestamp. If your application uses, for example, Redis, it’s worth delving into the subject. However, I do not want to replicate content from the documentation in this article. For a standard application (even a highly developed one), the basic configuration is entirely sufficient.

Basic Usage

Although the most significant added value of Snowflake is the direct use of them as primary keys on tables, we can also take advantage of the package benefits in other parts of the application.

The package provides us with a helper, which we call in the following way:

snowflake();

A number consistent with the Snowflake standard will be returned. The number is typed into a string, which is very beneficial if we send it to the front-end (JavaScript does not like large numerical types and likes to round them).

Migrations

The package provides several methods for migrating our tables. The absolute basis is to replace the standard $table->id(); with $table->snowflake('id')->primary();

If you look at the result in the database, we get the same column type in both cases (BigInteger, unsigned, primary key), with the difference that our snowflake does not have autoincrement value.

If for some reasons you want to replace standard ID with Snowflake in current migration files, I suggest doing the following:

Create a migration modification file:

php artisan make:migration replace_id_with_snowflake_in_{here_name_your_table}_table --table={here_name_your_table}

Keys in Tables

Until now in Laravel, you used such a method: $table->foreignId('user_id');

When using the caneara/snowflake package, use the following notation: $table->foreignSnowflake('user_id');

Remember that the key in the foreign table (in this case, user_id) should also be generated by the method discussed above.

Typically, the key does not have specific additional parameters. We provide them according to the existing methods in Laravel, e.g., $table->foreignSnowflake('user_id')->constrained()->cascadeOnDelete();

Then, we inform our model to now use Snowflake. We do this by adding a Trait to our model class, e.g.:

namespace App\Models;
use Snowflake\Snowflakes; // add

class User extends Model
{
    use Snowflakes; // add
}

As mentioned earlier, the package offers returning Snowflake in string type, which is practically a “must-have” for all frontend applications.

Casting

Laravel offers very efficient casting of object values. The same is true for Snowflake. When saving, we want it to be an integer, but for reading, we need a string. The package provides these methods automatically. We just inform Laravel:

Laravel in version 11 changes the approach to casting, so I will present two approaches, on the User model class:

Up to Laravel 10:

namespace App\Models;

use Snowflake\Snowflakes;
use Snowflake\SnowflakeCast; // add
class User extends Model
{
    use Snowflakes;
    protected $casts = [
        'id' => SnowflakeCast::class, // add
    ];
}

From Laravel 11:

protected function casts(): array
{
    return [
        'id' => SnowflakeCast::class,
    ];
}

Additional information regarding cast changes: This update is backward compatible with Laravel 10, and you can still define casting using the $casts property combined with the new casts() method. The $casts property and casts() method are merged, with method keys taking precedence over the $casts property.

After such modifications, our model now fully utilizes Snowflake. Snowflake can also be used in parts of the application like factories or seeders.

However, it is essential to note a very important issue at the end. You must know that the identifier generated by the Snowflake algorithm is not guaranteed to be unique. For example, if two different requests enter the same node of the same data center at the same time, and the sequence generated by the node is the same, the generated identifier will be duplicated. If you want to use the Snowflake algorithm to generate a unique identifier, you must ensure that the serial number generated in the same millisecond by the same node is unique. This problem is particularly troublesome when generating a large amount of data in seeders. How to solve it? In the configuration mentioned at the beginning, increase the number of data centers, but keep moderation in their number, as too many can affect the application’s performance. For Seeders, which can generate more records than 1 per ms, 2–3 data centers set in the configuration are sufficient.

Summary

In this article, we embarked on the task of exploring the topic of Snowflake identifiers, from theoretical foundations through the process of choosing the right package, to detailed implementation in the Laravel environment. We presented step-by-step how to install and configure the caneara/snowflake package, how to utilize it in migrations and models, and how to deal with potential challenges related to the uniqueness of identifiers. Thanks to this guide, Laravel users are equipped with all the necessary information to effectively implement and use Snowflake in their projects, contributing to the optimization of database work and increasing the efficiency of sorting data "in time."

If you enjoyed this article, consider trying out the AI service I recommend. It provides the same performance and functions to ChatGPT Plus(GPT-4) but more cost-effective, at just $6/month (Special offer for $1/month). Click here to try ZAI.chat.

Laravel
Laravel Framework
Programming
Code
PHP
Recommended from ReadMedium