前書き
インストール
このプロジェクトは ent
と呼ばれるコード生成ツールを備えています。 ent
をインストールするには、次のコマンドを実行します。
go get -d entgo.io/ent/cmd/ent
新しいスキーマの初期化
1つまたは複数のスキーマテンプレートを生成するには、次のように ent
を実行します。
go run -mod=mod entgo.io/ent/cmd/ent new User Pet
init
は、ent/schema
ディレクトリの下にスキーマ( user.go
と pet.go
) の2つを作成します。 ent
ディレクトリが存在しない場合は、ディレクトリも作成します。 通常はプロジェクトのルートディレクトリの下に ent
ディレクトリを保持します。
アセットの生成
After adding a few fields and edges, you want to generate the assets for working with your entities. プロジェクトのルートディレクトリから ent generate
を実行するか、 を使用する go generate
を使用してください:
go generate ./ent
generate
コマンドは、スキーマの以下のアセットを生成します:
Client
とTx
オブジェクトはグラフとのやり取りに使用されます。- 各スキーマ型の CRUD ビルダー。 See CRUD for more info.
- 各スキーマタイプのエンティティオブジェクト (Go struct)。
- ビルダーとの相互作用に使用される定数と述語を含むパッケージ。
- SQLの
migrate
パッケージ。 詳細はMigrationを参照してください。 - mutationミドルウェアを追加するための
hook
パッケージ。 詳細は Hooks を参照してください。
entc
と ent
のバージョンを一致させる
プロジェクトでent
CLIを使用する場合、CLIで使用されているバージョンがプロジェクトで使用されているent
のバージョンと同じである確証が欲しいと思います
これを実現するための選択肢の1つは、ent
の実行時にgo.mod
ファイルに記載されているバージョンを使用するようにgo generate
で指定することです。 プロジェクトでGo modulesを使用していない場合は、以下のように設定します:
go mod init <project>
go.mod
ファイルに ent
を追加するには、次のコマンドを再実行します:
go get -d entgo.io/ent/cmd/ent
generate.go
ファイルを、<project>/ent
の下に追加します:
package ent
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema
最後に、プロジェクトのルートディレクトリからgo generate ./ent
を実行すると、プロジェクトのスキーマに対してent
コード生成を行うことができます。
コード生成オプション
コード生成オプションの詳細については、 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
ストレージオプション
ent
はSQLとGremlinの両方の方言のアセットを生成することができます。 デフォルトの方言はSQLです。
外部テンプレート
ent
は、コード生成の際に外部Go テンプレートを受け付けます。 テンプレート名がent
によって既に定義されている場合は、既存のテンプレートを上書きします。 それ以外の場合は、実行出力をテンプレートと同じ名前のファイルに書き込みます。 フラグは以下のように file
、 dir
および glob
の形式をサポートしています:
go run -mod=mod entgo.io/ent/cmd/ent generate --template <dir-path> --template glob="path/to/*.tmpl" ./ent/schema
詳しい情報と例は、 外部テンプレートドキュメント にあります。
entc
をパッケージとして使用する
ent
のコード生成を実行する別の選択肢があります。次のコードを含むent/entc.go
という名前のファイルを作成し、次にent/generate.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)
}
}
package ent
//go:generate go run -mod=mod entc.go
完全な例は GitHub にあります。
スキーマの詳細
グラフスキーマの説明を取得するには、以下を実行してください:
go run -mod=mod entgo.io/ent/cmd/ent describe ./ent/schema
出力の例は以下のとおりです。
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 |
+------+------+---------+---------+----------+--------+----------+
コード生成フック
entc
パッケージは、コード生成フェーズにフック(ミドルウェア) のリストを追加するオプションを提供します。 このオプションは、スキーマにカスタムバリデータを追加したり、グラフ スキーマを使用して追加のアセットを生成したりするのに最適です。
// +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)
})
}
}
External Dependencies
In order to extend the generated client and builders under the ent
package, and inject them external dependencies as struct fields, use the entc.Dependency
option in your ent/entc.go
file:
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)
}
}
Then, use it in your application:
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)
})
})
// ...
}
The full example exists in GitHub.
Feature Flags
The entc
package provides a collection of code-generation features that be added or removed using flags.
For more information, please see the features-flags page.