ent para Go: Guia completo de ORM com geração de código
No mundo do desenvolvimento em Go, existem várias bibliotecas ORM, mas o ent do Facebook (agora Meta) ocupa um lugar especial. Não é apenas mais um ORM — é um framework poderoso para trabalhar com bancos de dados, baseado em geração de código. Em vez de usar reflexão ou interfaces em tempo de execução, o ent gera código Go estritamente tipado com base no seu esquema de dados. Isso significa que muitos erros relacionados a tipos e consultas são detectados em tempo de compilação, e não em produção.
Por que usar o ent? Se você trabalha com bancos de dados relacionais (PostgreSQL, MySQL, SQLite) e quer ter tipagem forte, autocompletar na IDE e o mínimo de código boilerplate — o ent é a sua escolha. Ele é ideal para projetos onde desempenho e manutenibilidade do código são importantes. Ao contrário do GORM, que usa reflexão, o ent gera código para cada modelo, tornando-o significativamente mais rápido e seguro.
Neste artigo, vamos detalhar o ent: desde a instalação até técnicas avançadas. Você aprenderá como definir um esquema de dados, gerar código, executar operações CRUD, construir consultas complexas com grafos de relacionamentos e evitar erros comuns. O material é voltado para desenvolvedores que já conhecem os fundamentos do Go.
Instalação
Para começar a trabalhar com o ent, você precisa do Go versão 1.16 ou superior. A instalação inclui o pacote ent em si e a ferramenta de linha de comando para geração de código.
# Instalação da ferramenta de linha de comando
go install entgo.io/ent/cmd/ent@latest
# Inicialização do projeto (cria o diretório ent/)
go run entgo.io/ent/cmd/ent init User
O primeiro comando instala o binário ent no seu $GOPATH/bin. O segundo comando cria a estrutura do projeto: um diretório ent/ com o arquivo de esquema para a entidade User. Depois disso, você pode começar a definir campos e relacionamentos.
Início rápido: exemplo mínimo funcional
Vamos criar um modelo simples de usuário e executar operações básicas. Primeiro, defina o esquema no arquivo ent/schema/user.go:
package schema
import (
"entgo.io/ent"
"entgo.io/ent/schema/field"
)
// User holds the schema definition for the User entity.
type User struct {
ent.Schema
}
// Fields of the User.
func (User) Fields() []ent.Field {
return []ent.Field{
field.String("name").
Unique().
NotEmpty(),
field.Int("age").
Positive(),
field.String("email").
Unique(),
}
}
Agora, gere o código:
go generate ./ent
Depois disso, você pode usar o código gerado no main.go:
package main
import (
"context"
"fmt"
"log"
"your-project/ent"
"your-project/ent/user"
_ "github.com/mattn/go-sqlite3"
)
func main() {
// Cria um cliente para SQLite (em memória)
client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
if err != nil {
log.Fatalf("falha ao abrir conexão com sqlite: %v", err)
}
defer client.Close()
// Migração automática do esquema
ctx := context.Background()
if err := client.Schema.Create(ctx); err != nil {
log.Fatalf("falha ao criar recursos do esquema: %v", err)
}
// Cria um usuário
u, err := client.User.
Create().
SetName("Alice").
SetAge(30).
SetEmail("alice@example.com").
Save(ctx)
if err != nil {
log.Fatalf("falha ao criar usuário: %v", err)
}
fmt.Printf("Usuário criado: %+v\n", u)
// Busca um usuário pelo nome
found, err := client.User.
Query().
Where(user.NameEQ("Alice")).
Only(ctx)
if err != nil {
log.Fatalf("falha ao consultar usuário: %v", err)
}
fmt.Printf("Usuário encontrado: %+ Também na biblioteca
Burn para Rust: guia completo com exemplos práticos
Criptografia em Node.js: criptografia e hash com crypto
StackExchange.Redis para C# (.NET): guia completo com exemplos práticos