Saltar al contenido principal

Introducción

[Traducción Beta No Oficial]

Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →

Instalación

El proyecto incluye una herramienta de generación de código llamada ent. Para instalar ent, ejecuta el siguiente comando:

go get entgo.io/ent/cmd/ent

Inicializar un nuevo esquema

Para generar una o más plantillas de esquema, ejecuta ent init de la siguiente manera:

go run -mod=mod entgo.io/ent/cmd/ent new User Pet

init creará los 2 esquemas (user.go y pet.go) en el directorio ent/schema. Si el directorio ent no existe, también lo creará. La convención es tener un directorio ent en la raíz del proyecto.

Generar recursos

Después de añadir algunos campos y relaciones, puedes generar los recursos para trabajar con tus entidades. Ejecuta ent generate desde el directorio raíz del proyecto, o usa go generate:

go generate ./ent

El comando generate crea los siguientes recursos para los esquemas:

  • Objetos Client y Tx para interactuar con el grafo.

  • Constructores CRUD para cada tipo de esquema. Más información en CRUD.

  • Objetos de entidad (structs de Go) para cada tipo de esquema.

  • Paquete con constantes y predicados para interactuar con los constructores.

  • Un paquete migrate para dialectos SQL. Consulta Migración para más información.

  • Paquete hook para añadir middlewares de mutación. Más información en Hooks.

Compatibilidad de versiones entre entc y ent

Al usar la CLI de ent en un proyecto, asegúrate de que la versión utilizada por la CLI sea idéntica a la versión de ent usada en tu proyecto.

Una opción para lograrlo es configurar go generate para usar la versión especificada en el archivo go.mod al ejecutar ent. Si tu proyecto no usa Go modules, configúralo así:

go mod init <project>

Luego, vuelve a ejecutar este comando para añadir ent a tu go.mod:

go get entgo.io/ent/cmd/ent

Añade un archivo generate.go en tu proyecto bajo <project>/ent:

package ent

//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema

Finalmente, ejecuta go generate ./ent desde el directorio raíz de tu proyecto para aplicar la generación de código ent a tus esquemas.

Opciones de generación de código

Para más información sobre opciones de generación, ejecuta ent generate -h:

generate go code for the schema directory

Usage:
ent generate [flags] path

Examples:
ent generate ./ent/schema
ent generate github.com/a8m/x

Flags:
--feature strings extend codegen with additional features
--header string override codegen header
-h, --help help for generate
--storage string storage driver to support in codegen (default "sql")
--target string target directory for codegen
--template strings external templates to execute

Opciones de almacenamiento

ent puede generar recursos para dialectos SQL y Gremlin. El dialecto predeterminado es SQL.

Plantillas externas

ent acepta plantillas externas de Go para ejecutar. Si el nombre de la plantilla ya está definido por ent, sobrescribirá la existente. En caso contrario, escribirá la salida en un archivo con el mismo nombre que la plantilla. El formato de los flags admite file, dir y glob así:

go run -mod=mod entgo.io/ent/cmd/ent generate --template <dir-path> --template glob="path/to/*.tmpl" ./ent/schema

Más información y ejemplos en la documentación de plantillas externas.

Usar entc como paquete

Otra opción para ejecutar la generación de código ent es crear un archivo ent/entc.go con este contenido, y luego el archivo ent/generate.go para ejecutarlo:

ent/entc.go
// +build ignore

package main

import (
"log"

"entgo.io/ent/entc"
"entgo.io/ent/entc/gen"
"entgo.io/ent/schema/field"
)

func main() {
if err := entc.Generate("./schema", &gen.Config{}); err != nil {
log.Fatal("running ent codegen:", err)
}
}
ent/generate.go
package ent

//go:generate go run -mod=mod entc.go

El ejemplo completo está disponible en GitHub.

Descripción del esquema

Para obtener una descripción de tu esquema de grafo, ejecuta:

go run -mod=mod entgo.io/ent/cmd/ent describe ./ent/schema

Un ejemplo de la salida sería:

Pet:
+-------+---------+--------+----------+----------+---------+---------------+-----------+-----------------------+------------+
| Field | Type | Unique | Optional | Nillable | Default | UpdateDefault | Immutable | StructTag | Validators |
+-------+---------+--------+----------+----------+---------+---------------+-----------+-----------------------+------------+
| id | int | false | false | false | false | false | false | json:"id,omitempty" | 0 |
| name | string | false | false | false | false | false | false | json:"name,omitempty" | 0 |
+-------+---------+--------+----------+----------+---------+---------------+-----------+-----------------------+------------+
+-------+------+---------+---------+----------+--------+----------+
| Edge | Type | Inverse | BackRef | Relation | Unique | Optional |
+-------+------+---------+---------+----------+--------+----------+
| owner | User | true | pets | M2O | true | true |
+-------+------+---------+---------+----------+--------+----------+

User:
+-------+---------+--------+----------+----------+---------+---------------+-----------+-----------------------+------------+
| Field | Type | Unique | Optional | Nillable | Default | UpdateDefault | Immutable | StructTag | Validators |
+-------+---------+--------+----------+----------+---------+---------------+-----------+-----------------------+------------+
| id | int | false | false | false | false | false | false | json:"id,omitempty" | 0 |
| age | int | false | false | false | false | false | false | json:"age,omitempty" | 0 |
| name | string | false | false | false | false | false | false | json:"name,omitempty" | 0 |
+-------+---------+--------+----------+----------+---------+---------------+-----------+-----------------------+------------+
+------+------+---------+---------+----------+--------+----------+
| Edge | Type | Inverse | BackRef | Relation | Unique | Optional |
+------+------+---------+---------+----------+--------+----------+
| pets | Pet | false | | O2M | false | true |
+------+------+---------+---------+----------+--------+----------+

Ganchos de generación de código

El paquete entc ofrece la opción de añadir una lista de ganchos (middlewares) a la fase de generación de código. Esta funcionalidad es ideal para añadir validadores personalizados al esquema o para generar activos adicionales utilizando el esquema del grafo.

// +build ignore

package main

import (
"fmt"
"log"
"reflect"

"entgo.io/ent/entc"
"entgo.io/ent/entc/gen"
)

func main() {
err := entc.Generate("./schema", &gen.Config{
Hooks: []gen.Hook{
EnsureStructTag("json"),
},
})
if err != nil {
log.Fatalf("running ent codegen: %v", err)
}
}

// EnsureStructTag ensures all fields in the graph have a specific tag name.
func EnsureStructTag(name string) gen.Hook {
return func(next gen.Generator) gen.Generator {
return gen.GenerateFunc(func(g *gen.Graph) error {
for _, node := range g.Nodes {
for _, field := range node.Fields {
tag := reflect.StructTag(field.StructTag)
if _, ok := tag.Lookup(name); !ok {
return fmt.Errorf("struct tag %q is missing for field %s.%s", name, node.Name, field.Name)
}
}
}
return next.Generate(g)
})
}
}

Dependencias externas

Para extender el cliente generado y los constructores (builders) del paquete ent, e inyectarles dependencias externas como campos de estructura, utiliza la opción entc.Dependency en tu archivo ent/entc.go:

ent/entc.go
func main() {
opts := []entc.Option{
entc.Dependency(
entc.DependencyType(&http.Client{}),
),
entc.Dependency(
entc.DependencyName("Writer"),
entc.DependencyTypeInfo(&field.TypeInfo{
Ident: "io.Writer",
PkgPath: "io",
}),
),
}
if err := entc.Generate("./schema", &gen.Config{}, opts...); err != nil {
log.Fatalf("running ent codegen: %v", err)
}
}

Luego, utilízalo en tu aplicación:

example_test.go
func Example_Deps() {
client, err := ent.Open(
"sqlite3",
"file:ent?mode=memory&cache=shared&_fk=1",
ent.Writer(os.Stdout),
ent.HTTPClient(http.DefaultClient),
)
if err != nil {
log.Fatalf("failed opening connection to sqlite: %v", err)
}
defer client.Close()
// An example for using the injected dependencies in the generated builders.
client.User.Use(func(next ent.Mutator) ent.Mutator {
return hook.UserFunc(func(ctx context.Context, m *ent.UserMutation) (ent.Value, error) {
_ = m.HTTPClient
_ = m.Writer
return next.Mutate(ctx, m)
})
})
// ...
}

El ejemplo completo está disponible en GitHub.

Banderas de características

El paquete entc ofrece una colección de características de generación de código que pueden añadirse o eliminarse mediante banderas.

Para más información, consulta la página de banderas de características.