Como gerar UUIDs automaticamente para seus models do Laravel — Parte I

João Roberto da Paixão
Training Center
Published in
4 min readMay 16, 2018

TL;DR

Desenvolvi um pacote simples, flexível, de fácil customização e 100% coberto por testes automatizados que facilita a geração de UUIDs automaticamente nos models Eloquent do Laravel.

Introdução

Um UUID é um identificador universalmente exclusivo utilizado para identificação de qualquer coisa no mundo da computação.

Eu escrevi um artigo bem detalhado sobre o que é UUID? Porque usá-lo? Se você ainda não conhece, ou não leu esse artigo, recomendo fortemente que faço isso agora.

Um pouco de história…

No PHP existe uma excelente biblioteca para lidar com a geração de UUIDs: https://github.com/ramsey/uuid .

Para gerar um UUID na versão 4, basta isso:

Uuid::uuid4();

O que pouca gente sabe é que essa biblioteca está incluída nas dependências do Laravel Framework desde a sua versão 5.3 . Ou seja, quando você instala o Laravel 5.3 ou superior, automaticamente a biblioteca Ramsey/Uuid já está disponível na pasta Vendor da aplicação e você pode utiliza-la em qualquer lugar do seu projeto.

A versão 5.6 do Laravel introduziu novos métodos pra geração de UUID na classe Illuminate/Support/Str.php, esses métodos utilizam a biblioteca Ramsey/Uuid. Isso acabou popularizando um pouco mais o UUID no ecossistema Laravel.

Agora, prometo que vou parar de enrolação e vou direto ao assunto desse artigo.

Gerando UUIDs automaticamente — Eloquent Laravel

Isso é algo relativamente simples de se fazer, basta “escutar” o evento creating do Eloquent — passando pra ele uma função anônima com a lógica responsável pela geração do UUID. Uma maneira eficiente de se fazer isso é criar uma Trait contendo essa lógica, veja:

<?phpnamespace App\Traits;use Ramsey\Uuid\Uuid;trait Uuid
{
public static function bootUuid()
{
static::creating(function ($model) {
$model->uuid = Uuid::uuid4();
});
}
}

Agora basta utilizar essa Trait no seu model e pronto! O model em questão irá receber um UUID — gerado pela classe Ramsey\Uuid — automaticamente no momento em que um novo registro for inserido na base de dados.

<?php// app\User.phpuse App\Traits\Uuid;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use Uuid;
// ...
}
// ATENÇÃO: Esse código é apenas pra ilustrar o uso da Trait Uuid em um model Eloquent qualquer... Não use esse exemplo na sua aplicação!

Nota: Se você não conhece a maneira como o model carrega esse tipo de Trait no Eloquent, recomendo a leitura desse artigo: Laravel além do básico: #1 — Bootable traits no Eloquent.

Dando continuidade, essa abordagem é uma das mais simples possível! Agora convenhamos, nos tempos atuais desenvolver o mínimo não basta… Por ser bastante simples, esse exemplo de Trait acaba sendo bastante limitado e engessado.

Não reinvente a roda — Usando Pacotes!

Claro que já existem diversos pacotes do Laravel que abstraem toda essa lógica, o que acaba facilitando e muito nosso trabalho. Porém, ao testar alguns dos pacotes mais populares notei vários pontos que estavam me incomodando e que mereciam um pouco de atenção. Seguem abaixo:

  • Não possuíam testes automatizados… Como eu posso confiar em uma dependência de terceiro que não possui testes? E se o mantenedor mexer em algo e lançar uma release com bug… Pra evitar constrangimentos eu prefiro não depender de algo que não possui testes, simples assim!
  • Assumiam que a coluna que representa o ‘uuid’ na base de dados, sempre teria esse nome de ‘uuid’. Mas, o banco de dados é meu, e se eu quiser colocar outro nome como por exemplo ‘universally_unique_id’ ou simplismente ‘id’? Problema detectado!
  • Não forneciam uma proteção caso o usuário tenta-se alterar o uuid na atualização dos dados. (usuários nunca devem ser capazes de gerar seus próprios UUIDs nem podem substituí-los). Problema detectado!
  • Não permitiam trocar a versão do UUID gerado. Exemplo: O pacote gerava UUID na versão 4. Mas, se eu quiser gerar um UUID na versão 3 ou qualquer outra versão? Problema detectado!
  • Assumiam que o ‘uuid’ seria sempre a chave primária da tabela. Mas, se eu quiser manter as chaves primarias ID auto-increment pra uso interno e usar os UUIDs como referência nas URLs? Problema detectado!
  • Não forneciam uma maneira fácil de serem customizados ou ‘extensíveis’. (Não chega a ser um problema, mas seria uma comodidade.)
  • Não forneciam uma scope query para facilitar a busca no model através de UUID. (Não chega a ser um problema, mas seria uma comodidade.)
  • Não forneciam suporte para utilizar implicit model binding. (Não chega a ser um problema, mas seria uma comodidade.)

Obviamente que os pontos citados acima foram encontrados de forma aleatória nos pacotes que eu testei. Juntando tudo isso veio a motivação para criar um pacote que “resolveria” tudo que estava me incomodando. Foi assim que nasceu o your-app-rocks/eloquent-uuid .

Por hoje é só! na parte 2 desse artigo eu explico detalhadamente como utilizar o pacote.

̶C̶o̶m̶o̶ ̶g̶e̶r̶a̶r̶ ̶U̶U̶I̶D̶s̶ ̶a̶u̶t̶o̶m̶a̶t̶i̶c̶a̶m̶e̶n̶t̶e̶ ̶p̶a̶r̶a̶ ̶s̶e̶u̶s̶ ̶m̶o̶d̶e̶l̶s̶ ̶d̶o̶ ̶L̶a̶r̶a̶v̶e̶l̶ ̶ — ̶ ̶P̶a̶r̶t̶e̶ ̶2̶ (Ainda trabalhando nisso! Aguarde…)

--

--

João Roberto da Paixão
Training Center

Eterno aprendiz que compartilha aquilo que aprende. Apaixonado por tecnologia, desenvolvimento pessoal e investimentos. Pai de família, um cara tranquilo =) !