Saltar al contenido principal

Extensiones

[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 →

Introducción

La API de Extensiones de Ent facilita la creación de extensiones de generación de código que agrupan hooks de codegen, plantillas y anotaciones para crear componentes reutilizables que añaden nueva funcionalidad avanzada al núcleo de Ent. Por ejemplo, el plugin entgql expone una Extension que genera automáticamente servidores GraphQL a partir de un esquema Ent.

Definir una nueva extensión

Todas las extensiones deben implementar la interfaz Extension:

type Extension interface {
// Hooks holds an optional list of Hooks to apply
// on the graph before/after the code-generation.
Hooks() []gen.Hook

// Annotations injects global annotations to the gen.Config object that
// can be accessed globally in all templates. Unlike schema annotations,
// being serializable to JSON raw value is not mandatory.
//
// {{- with $.Config.Annotations.GQL }}
// {{/* Annotation usage goes here. */}}
// {{- end }}
//
Annotations() []Annotation

// Templates specifies a list of alternative templates
// to execute or to override the default.
Templates() []*gen.Template

// Options specifies a list of entc.Options to evaluate on
// the gen.Config before executing the code generation.
Options() []Option
}

Para simplificar el desarrollo de nuevas extensiones, los desarrolladores pueden incrustar entc.DefaultExtension para crear extensiones sin implementar todos los métodos:

package hello

// GreetExtension implements entc.Extension.
type GreetExtension struct {
entc.DefaultExtension
}

Añadiendo plantillas

Ent permite añadir plantillas externas que se renderizarán durante la generación de código. Para incluir estas plantillas en una extensión, implementa el método Templates:

templates/greet.tmpl
{{/* Tell Intellij/GoLand to enable the autocompletion based on the *gen.Graph type. */}}
{{/* gotype: entgo.io/ent/entc/gen.Graph */}}

{{ define "greet" }}

{{/* Add the base header for the generated file */}}
{{ $pkg := base $.Config.Package }}
{{ template "header" $ }}

{{/* Loop over all nodes and add the Greet method */}}
{{ range $n := $.Nodes }}
{{ $receiver := $n.Receiver }}
func ({{ $receiver }} *{{ $n.Name }}) Greet() string {
return "Hello, {{ $n.Name }}"
}
{{ end }}

{{ end }}
func (*GreetExtension) Templates() []*gen.Template {
return []*gen.Template{
gen.MustParse(gen.NewTemplate("greet").ParseFiles("templates/greet.tmpl")),
}
}

Añadir anotaciones globales

Las anotaciones son una forma práctica de proporcionar a los usuarios de nuestra extensión una API para modificar el comportamiento de la generación de código. Para añadir anotaciones a nuestra extensión, implementa el método Annotations. Supongamos que en nuestra GreetExtension queremos permitir a los usuarios configurar la palabra de saludo en el código generado:

// GreetingWord implements entc.Annotation.
type GreetingWord string

// Name of the annotation. Used by the codegen templates.
func (GreetingWord) Name() string {
return "GreetingWord"
}

Luego añádelo a la estructura GreetExtension:

type GreetExtension struct {
entc.DefaultExtension
word GreetingWord
}

Luego, implementamos el método Annotations:

func (s *GreetExtension) Annotations() []entc.Annotation {
return []entc.Annotation{
s.word,
}
}

Ahora, desde tus plantillas puedes acceder a la anotación GreetingWord:

func ({{ $receiver }} *{{ $n.Name }}) Greet() string {
return "{{ $.Annotations.GreetingWord }}, {{ $n.Name }}"
}

Añadir hooks

El paquete entc ofrece una opción para añadir una lista de hooks (middlewares) a la fase de generación de código. Esta opción es ideal para añadir validadores personalizados al esquema, o para generar recursos adicionales usando el esquema gráfico. Para incluir hooks de generación de código en tu extensión, implementa el método Hooks:

func (s *GreetExtension) Hooks() []gen.Hook {
return []gen.Hook{
DisallowTypeName("Shalom"),
}
}

// DisallowTypeName ensures there is no ent.Schema with the given name in the graph.
func DisallowTypeName(name string) gen.Hook {
return func(next gen.Generator) gen.Generator {
return gen.GenerateFunc(func(g *gen.Graph) error {
for _, node := range g.Nodes {
if node.Name == name {
return fmt.Errorf("entc: validation failed, type named %q not allowed", name)
}
}
return next.Generate(g)
})
}
}

Usar una extensión en generación de código

Para usar una extensión en nuestra configuración de generación de código, utiliza entc.Extensions, un método auxiliar que devuelve un entc.Option que aplica nuestras extensiones seleccionadas:

ent/entc.go
//+build ignore

package main

import (
"fmt"
"log"

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

func main() {
err := entc.Generate("./schema",
&gen.Config{},
entc.Extensions(&GreetExtension{
word: GreetingWord("Shalom"),
}),
)
if err != nil {
log.Fatal("running ent codegen:", err)
}
}

Extensiones de la comunidad

  • entoas entoas es una extensión que proviene de elk y se convirtió en su propia extensión, siendo ahora el generador oficial para documentos OpenAPI Specification con enfoque opinado. Puedes usarlo para desarrollar y documentar rápidamente un servidor HTTP RESTful. Próximamente se lanzará una nueva extensión que proporcionará una implementación generada que integre el documento proporcionado por entoas usando ent.

  • entrest entrest es una alternativa a entoas (+ ogent) y elk (antes de su descontinuación). entrest genera una especificación OpenAPI conforme, eficiente y completa desde tu esquema Ent, junto con una implementación funcional de servidor API RESTful. Sus características destacadas incluyen: paginación opcional, capacidades avanzadas de filtrado/consulta, ordenación (incluso a través de relaciones), carga ansiosa de edges, y mucho más.

  • entgql
    Esta extensión ayuda a los usuarios a construir servidores GraphQL a partir de esquemas de Ent. entgql se integra con gqlgen, una popular biblioteca Go con enfoque en esquemas primero para construir servidores GraphQL. La extensión incluye la generación de filtros GraphQL con seguridad de tipos, que permiten mapear consultas GraphQL a consultas de Ent sin esfuerzo.
    Sigue este tutorial para comenzar.

  • entproto
    entproto genera definiciones de mensajes Protobuf y servicios gRPC a partir de esquemas de Ent. El proyecto también incluye protoc-gen-entgrpc, un plugin para protoc (compilador de Protobuf) que genera una implementación funcional de los servicios gRPC definidos por Entproto. Así podemos crear fácilmente un servidor gRPC capaz de atender solicitudes sin escribir código (¡excepto definiendo el esquema de Ent)!
    Para aprender a usar y configurar entproto, lee este tutorial. Para más contexto, puedes leer esta entrada de blog o esta otra sobre características avanzadas de entproto.

  • elk (descontinuado)
    elk era una extensión que generaba endpoints de API RESTful a partir de esquemas de Ent. Generaba manejadores HTTP CRUD y un archivo JSON OpenAPI. Permitía construir fácilmente servidores HTTP RESTful para aplicaciones. Ten en cuenta que elk se descontinuó en favor de entoas. Actualmente se trabaja en un generador de implementación alternativo. Lee esta entrada de blog sobre cómo trabajar con elk, y esta otra sobre generación de Especificaciones OpenAPI.

  • entviz (descontinuado)
    entviz era una extensión que generaba diagramas visuales de esquemas de Ent. Estos diagramas se visualizaban en navegadores web y se actualizaban automáticamente durante el desarrollo. entviz permitía configurar actualizaciones automáticas al regenerar esquemas, facilitando ver los cambios en tiempo real.
    Aprende a integrar entviz en esta entrada de blog. Esta extensión fue archivada por su mantenedor el 2023-09-16.