メインコンテンツへスキップする

entviz を使用してデータグラフを視覚化する

· 1 分で読む

大規模なコードベースを持つ既存のプロジェクトに参加することは、困難な作業です。

アプリケーションのデータモデルを理解することは、開発者が既存のプロジェクトに取り組む際の鍵となります。 ER (Entity Relation) 図は、この課題を克服し、開発者がアプリケーションのデータモデルを把握するためによく使われるツールです。

ER図は、データモデルを視覚的に表現するもので、エンティティの各フィールドを詳細に示しています。 多くのツールがこれらを作成するのに役立ちます。たとえばJetbrain DataGripです。 既存のデータベースに接続して検査することでER図を生成きます。

Datagrip ER diagram

DataGrip ER 図の例

Entは、シンプルで強力なGoのためのエンティティフレームワークで、元々は大規模で複雑なデータモデルのプロジェクトに対応するために、Facebook社内で開発されました。 Entがコード生成を使用するのはこのためです。型安全性とコード補完をすぐに行うことで、データモデルの説明を助け、開発者の速度を向上させます。 さらに、データモデルのハイレベルなビューを維持するER図を、視覚的に魅力的な表現で自動的に生成できたら素晴らしいと思いませんか? (視覚的な表現が嫌いな人はいないでしょう)

entvizの導入

entviz は、データグラフを視覚化する静的な HTML ページを自動的に生成するent拡張です。

Entviz example output

Entviz 出力サンプル

ほとんどのERダイアグラム生成ツールは、データベースに接続し、それをイントロスペクトする必要があります。 データベーススキーマの最新のダイアグラムを維持するのが難しくなります entviz は Entスキーマに直接統合されているため、データベースに接続する必要はありません。 スキーマを変更するたびに自動的に新しい視覚化が生成されます

entviz がどのように実装されたかについて詳しく知りたい場合は、 内部実装 をご覧ください。

挙動を確認する

まず、entviz 拡張を entc.go ファイルに追加しましょう。

go get github.com/hedwigz/entviz
entc に詳しくない場合は、 entc documentation を読んでください。 :::
ent/entc.go
import (
"log"

"entgo.io/ent/entc"
"entgo.io/ent/entc/gen"
"github.com/hedwigz/entviz"
)

func main() {
err := entc.Generate("./schema", &gen.Config{}, entc.Extensions(entviz.Extension{}))
if err != nil {
log.Fatalf("running ent codegen: %v", err)
}
}

ユーザーエンティティといくつかのフィールドを持つ単純なスキーマがあるとします。

ent/schema/user.go
// Fields of the User.
func (User) Fields() []ent.Field {
return []ent.Field{
field.String("name"),
field.String("email"),
field.Time("created").
Default(time.Now),
}
}

これにより、entviz は実行するたびに自動的にグラフの視覚化を生成します。

go generate ./...

entディレクトリに schema-viz.html という新しいファイルが表示されるはずです:

$ ll ./ent/schema-viz.html
-rw-r--r-- 1 hedwigz hedwigz 7.3K Aug 27 09:00 schema-viz.html

HTMLファイルをお気に入りのブラウザで開き、表示を確認します

tutorial image

次に、Postという名前の別のエンティティを追加し、可視化がどのように変化するかを見てみましょう。

ent init Post
ent/schema/post.go
// Fields of the Post.
func (Post) Fields() []ent.Field {
return []ent.Field{
field.String("content"),
field.Time("created").
Default(time.Now),
}
}

次に、User から Post に (O2M)エッジを追加します。

ent/schema/post.go
// Edges of the User.
func (User) Edges() []ent.Edge {
return []ent.Edge{
edge.To("posts", Post.Type),
}
}

最後に、コードを再生成します。

go generate ./...

更新された結果を確認するにはブラウザを更新してください!

tutorial image 2

内部実装

Entvizはextension APIを用いてentを拡張することで実装されました。 Entのextension APIを使用すると、 templateshooksoptionsannotations.をまとめ上げることができます たとえば、entvizではテンプレートを使って、entviz.goという別のgoファイルを追加しています。このentviz.goはServeEntvizメソッドを公開しており、httpハンドラとして次のように使用できます。

func main() {
http.ListenAndServe("localhost:3002", ent.ServeEntviz())
}

デフォルトのextensionを埋め込むextension構造体を定義し、 Template メソッドを使用してテンプレートをエクスポートします。

//go:embed entviz.go.tmpl
var tmplfile string

type Extension struct {
entc.DefaultExtension
}

func (Extension) Templates() []*gen.Template {
return []*gen.Template{
gen.MustParse(gen.NewTemplate("entviz").Parse(tmplfile)),
}
}

テンプレートファイルは、生成するコードです。

{{ define "entviz"}}

{{ $pkg := base $.Config.Package }}
{{ template "header" $ }}
import (
_ "embed"
"net/http"
"strings"
"time"
)

//go:embed schema-viz.html
var html string

func ServeEntviz() http.Handler {
generateTime := time.Now()
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
http.ServeContent(w, req, "schema-viz.html", generateTime, strings.NewReader(html))
})
}
{{ end }}

以上です! entパッケージに新しいメソッドがあります

まとめ

ER図は、開発者がデータモデルを把握するのに役立つことがわかりました。 次に、EntスキーマのER図を自動生成するEnt拡張機能であるentvizを紹介しました。 entvizがEntの拡張APIを利用してコード生成を拡張し、追加機能を追加する方法を見ました。 最後に、自分のプロジェクトにentvizをインストールして使用することで、実際に動作を確認しました。 コードが気に入ったら、そして貢献したいと思ったら、githubでプロジェクトをチェックアウトすることができます。

さらにご質問がありますか? 始めるにあたって助けが必要ですか? Slack チャンネル に参加してください。

:::