In alcuni progetti potremmo aver bisogno di aggiungere degli identificatori generici, non-numerici, che possano comportarsi da ID. Può essere utile, come nel mio caso, proprio in progetti come API pubbliche per identificare modelli e risorse nelle risposte in sostituzione agli ID reali. Questo perché, in generale, non svelano nulla del nostro progetto: a differenza degli ID, non sono sequenziali e non mostrano alcunché dei nostri model, quanti ordini abbiamo, quanti utenti ha la nostra tabella users o quale ID sequenziale ha l’ordine appena inserito (e quindi quanti ordini abbiamo), e via dicendo. Insomma, proteggono alcune business metrics che potrebbero essere visibili all’esterno.
Breve anatomia di un UUID
UUID sta per Universal Unique Identifier ed è in sostanza una stringa da 128bit che è univoca in un determinato sistema. Ne esistono varie versioni, che differiscono per il modo in cui vengono generate. Nonostante ciò, quando genericamente ci riferiamo ad “uno UUID” facciamo riferimento quasi sempre alla versione 4, o v4 per gli amici. Un UUID v4 è lungo 36 caratteri ed è generato in modo randomico, come questo:
7cf03620-74c9-4e14-a2a4-9493e7378df5
In realtà, ogni suo “pezzo” è generato in modo casuale e non contiene informazioni sulla macchina, orario o rete di chi l’ha generato. Inoltre, è perfetto per gli ID, perché il numero possibile di UUID v4 generabili è 5.3 x 10^36, e non c’è rischio di collisioni.
Laravel ha inserito tra i suoi helper, specificamente in quello Str
, la possibilità di generare e controllare la validità degli UUID v4.
Preparare la migration
A questo punto, però, ogni tupla nel nostro database è identificata da un semplice (e classico) ID integer progressivo. La soluzione, nel mio caso, è stata quella di aggiungere la colonna uuid
allo schema esistente. Andiamo quindi a creare (o modificare) una migration utilizzando il metodo ->uuid()
per aggiungere un campo chiamato appunto uuid
:
Schema::table('users', function (Blueprint $table) { $table->uuid('uuid'); });
A questo punto, eseguiamo la migrazione con il comando php artisan migrate
per creare la colonna uuid
nella tabella, users
nel mio caso.
Utilizziamo gli eventi dei Model
Naturalmente, dovremmo adesso scrivere la parte che crea gli UUID per ciascun record che andremo ad inserire. Sfrutteremo gli eventi dei Model di Eloquent per interagire in modo astratto con le proprietà dei modelli e colonne delle tabelle. I Model Events di Eloquent vengono triggati in varie fasi del ciclo di vita di un Model, e sono:
retrieved
creating
created
updating
updated
saving
saved
deleting
deleted
restoring
restored
Quello che faremo è sfruttare l’evento creating
, che viene chiamato al momento della creazione di un nuovo record, subito prima dell’evento created
. Sarà nel “momento” del creating
quello nel quale inietteremo il nostro uuid nuovo di pacca per quel record.
use Illuminate\Support\Str; class User extends Model { protected static function boot() { parent::boot(); static::creating(function ($post) { $post->uuid = Str::uuid(); }); } }
Come vediamo, registriamo l’evento creating
utilizzando una closure nella funzione di boot()
e modifichiamo l’attributo uuid
del model, assegnandovi un UUID generato dall’helper Str::uuid()
. Ci troveremo così un UUID generato nella colonna uuid
.
Fatto. Ecco un modo molto semplice per utilizzare gli UUID in un progetto Laravel.