avatarAdrian Generous

Summary

The website content provides a comprehensive guide on implementing Snowflake identifiers in a Laravel application using the caneara/snowflake package, covering installation, usage, and addressing potential uniqueness issues.

Abstract

The article discusses the advantages of using Snowflake identifiers, particularly in Laravel applications, and provides a step-by-step tutorial on integrating the caneara/snowflake package. It begins with an overview of Snowflake's benefits, such as optimization and efficient sorting of temporal data, and references a previous article for deeper insights into Snowflake versus UUIDs. The installation process is outlined, emphasizing the package's flexibility for advanced configurations, especially for distributed systems using Redis. The guide proceeds with practical examples of using Snowflake as primary keys, modifying migrations, and adjusting models to accommodate the new identifier system. It highlights the package's ability to return Snowflake IDs as strings, which is crucial for front-end applications. The article also addresses casting in Laravel, providing code examples for both pre-Laravel 11 and Laravel 11+ versions. Finally, it concludes with a discussion on ensuring the uniqueness of Snowflake IDs, suggesting configuration adjustments for seeders to prevent duplication, and reiterates the package's role in optimizing database operations and data sorting.

Opinions

  • The author is a proponent of Snowflake identifiers, advocating for their use in Laravel applications for performance benefits.
  • The caneara/snowflake package is recommended for its advanced customization options and seamless integration with Laravel.
  • The author values the string format of Snowflake IDs for front-end interactions, considering it a significant advantage.
  • There is an acknowledgment of the potential non-uniqueness of Snowflake IDs under certain conditions, with practical solutions provided to mitigate this risk.
  • The article suggests that proper configuration of the Snowflake algorithm can lead to increased efficiency in database operations and data management within Laravel projects.

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."

Laravel
Laravel Framework
Programming
Code
PHP
Recommended from ReadMedium
avatarIsmat Babirli
Develop Microservice with Laravel

12 min read