扩展
介绍
Ent 扩展 API 支持代码生成扩展的创建,绑定 代码生成钩子、
模板 和 注解 来创建可重复使用的组件为 Ent 核心新增丰富的功能。
例如,Ent entgql 插件 暴露一个从 Ent 模式自动生成 GraphQL 服务器的 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
}
为简化新扩展的开发,开发者可在不实现全部方法的情况下嵌入 entc.DefaultExtension 来创建扩展:
package hello
// GreetExtension implements entc.Extension.
type GreetExtension struct {
entc.DefaultExtension
}
添加模板
Ent支持添加 外部模板,这些模板将在代码生成过程中进行渲染。
若要在扩展中打包此类外部模板,需实现 Templates 方法:
{{/* 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")),
}
}
添加全局注解
注解为用户提供了利用带有 API 的扩展修改代码生成行为的便捷方式。
需实现 Annotations 方法来注解扩展。
我们在 GreetExtension 中想为用户在生成代码中提供配置问候语的能力:
// GreetingWord implements entc.Annotation.
type GreetingWord string
// Name of the annotation. Used by the codegen templates.
func (GreetingWord) Name() string {
return "GreetingWord"
}
Then add it to the GreetExtension struct:
type GreetExtension struct {
entc.DefaultExtension
word GreetingWord
}
Next, implement the Annotations method:
func (s *GreetExtension) Annotations() []entc.Annotation {
return []entc.Annotation{
s.word,
}
}
现在在模板中可用访问 GreetingWord 注解:
func ({{ $receiver }} *{{ $n.Name }}) Greet() string {
return "{{ $.Annotations.GreetingWord }}, {{ $n.Name }}"
}
添加钩子
entc 包为代码生成阶段添加一系列 钩子 提供选项。
此选项适用于为模式添加自定义验证器、使用图模式生成额外资产。
实现 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)
})
}
}
在代码生成中使用扩展
使用 entc.Extensions 来在代码生成配置中使用扩展,这是返回应用选中扩展的 entc.Option 的辅助方法:
//+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)
}
}
社区扩展
-
entoas
entoas是一个源自elk的扩展,现已移植为独立扩展,并成为官方的 OpenAPI 规范文档生成器。 你可借助它快速开发并文档化 RESTful HTTP 服务器。 即将发布的新扩展将使用ent提供基于entoas的集成文件的生成式实现。 -
entrest
entrest是entoas(+ogent) 和elk(停用前)的替代方案。 它能从你的 Ent 模式生成符合规范、高效且功能完整的 OpenAPI 规范,同时实现功能完善的 RESTful API 服务器。 其亮点功能包括:可切换分页、高级筛选/查询能力、排序(甚至支持关系排序)、延迟加载边等众多特性。 -
entgql
此扩展程序可帮助用户基于 Ent 模式构建 GraphQL 服务器。entgql与广受欢迎的模式优先的 Go库 gqlgen 集成,用于构建GraphQL服务器。 该扩展包含生成类型安全的 GraphQL 过滤器,使用户能够轻松将 GraphQL 查询映射到 Ent 查询。 请按照 本教程 开始操作。 -
entproto
entproto能够从 Ent 模式生成 Protobuf 消息定义和 gRPC 服务定义。 该项目还包含protoc-gen-entgrpc,这是一个protoc(Protobuf 编译器)插件,用于为 Entproto 生成的 gRPC 服务定义生成可运行的实现。 通过这种方式,我们无需编写任何代码(除了定义 Ent 模式外),就能轻松创建一个能够处理服务请求的 gRPC 服务器!
要了解如何使用和配置entproto,请阅读 本教程。 若需更多背景知识,可参阅 这篇博客文章, 或 这篇 探讨 entproto` 更多功能的博客文章。 -
elk (停止维护)
elk 是一款扩展工具,可从 Ent 模式生成 RESTful API 端点。 该扩展能基于 Ent 模式生成 HTTP CRUD 处理程序,并输出 OpenAPI JSON 文件。 使用它,您可轻松为应用程序构建 RESTful HTTP 服务器。 请注意,elk已停止维护,建议改用entoas。目前正在开发中的生成器实现。
请参阅 这篇博客 了解如何使用elk, 以及 这篇博客 了解如何生成 OpenAPI 规范。 -
entviz (停止维护)
entviz是一个能从 Ent 模式生成可视化图表的扩展程序。 这些图表可在网页浏览器中直观呈现模式,并随开发进程实时更新。 通过配置entviz,每次重新生成模式时图表将自动更新,便于直观查看变更内容。
请参阅 此博客文章 了解如何在项目中集成 entviz。 该扩展程序已由维护者于 2023-09-16 存档。