ent pour Go : guide complet avec exemples

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

ent pour Go : Guide complet de l'ORM avec génération de code

Dans l'univers du développement en Go, il existe de nombreuses bibliothèques ORM, mais ent de Facebook (désormais Meta) occupe une place à part. Ce n'est pas un simple ORM de plus : c'est un framework puissant pour interagir avec les bases de données, basé sur la génération de code. Au lieu d'utiliser la réflexion ou des interfaces à l'exécution, ent génère un code Go fortement typé à partir de votre schéma de données. Cela signifie que de nombreuses erreurs liées aux types et aux requêtes sont détectées à la compilation, et non en production.

Pourquoi utiliser ent ? Si vous travaillez avec des bases de données relationnelles (PostgreSQL, MySQL, SQLite) et que vous souhaitez bénéficier d'un typage strict, de l'autocomplétion dans votre IDE et d'un minimum de code passe-partout, ent est fait pour vous. Il est idéal pour les projets où la performance et la maintenabilité du code sont cruciales. Contrairement à GORM qui utilise la réflexion, ent génère du code pour chaque modèle, ce qui le rend nettement plus rapide et plus sûr.

Dans cet article, nous allons explorer ent en détail : de l'installation aux techniques avancées. Vous apprendrez à définir un schéma de données, générer du code, effectuer des opérations CRUD, construire des requêtes complexes avec des graphes de relations et éviter les erreurs courantes. Ce contenu est destiné aux développeurs déjà familiers avec les bases de Go.

Installation

Pour commencer avec ent, vous avez besoin de Go version 1.16 ou supérieure. L'installation comprend le package ent lui-même ainsi que l'utilitaire en ligne de commande pour la génération de code.

# Installation de l'outil en ligne de commande
go install entgo.io/ent/cmd/ent@latest

# Initialisation du projet (crée le dossier ent/)
go run entgo.io/ent/cmd/ent init User

La première commande installe le binaire ent dans votre $GOPATH/bin. La seconde crée la structure du projet : un dossier ent/ avec un fichier de schéma pour l'entité User. Vous pouvez ensuite commencer à définir les champs et les relations.

Démarrage rapide : exemple minimal fonctionnel

Créons un modèle d'utilisateur simple et effectuons des opérations de base. Commençons par définir le schéma dans le fichier ent/schema/user.go :

package schema

import (
    "entgo.io/ent"
    "entgo.io/ent/schema/field"
)

// User contient la définition du schéma pour l'entité User.
type User struct {
    ent.Schema
}

// Fields de User.
func (User) Fields() []ent.Field {
    return []ent.Field{
        field.String("name").
            Unique().
            NotEmpty(),
        field.Int("age").
            Positive(),
        field.String("email").
            Unique(),
    }
}

Générons maintenant le code :

go generate ./ent

Ensuite, utilisons le code généré dans main.go :

package main

import (
    "context"
    "fmt"
    "log"

    "your-project/ent"
    "your-project/ent/user"

    _ "github.com/mattn/go-sqlite3"
)

func main() {
    // Création d'un client SQLite (en mémoire)
    client, err := ent.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1")
    if err != nil {
        log.Fatalf("échec de l'ouverture de la connexion à sqlite : %v", err)
    }
    defer client.Close()

    // Automigration du schéma
    ctx := context.Background()
    if err := client.Schema.Create(ctx); err != nil {
        log.Fatalf("échec de la création des ressources du schéma : %v", err)
    }

    // Création d'un utilisateur
    u, err := client.User.
        Create().
        SetName("Alice").
        SetAge(30).
        SetEmail("alice@example.com").
        Save(ctx)
    if err != nil {
        log.Fatalf("échec de la création de l'utilisateur : %v", err)
    }
    fmt.Printf("Utilisateur créé : %+v\n", u)

    // Recherche d'un utilisateur par nom
    found, err := client.User.
        Query().
        Where(user.NameEQ("Alice")).
        Only(ctx)
    if err != nil {
        log.Fatalf("échec de la requête utilisateur : %v", err)
    }
    fmt.Printf("Utilisateur trouvé : %+                    

Recommendations