ent では UUID 型がデフォルトでサポートされているのですが、それとは別に ULID を使う方法を解説します。
ULID の実装は https://github.com/oklog/ulid を使用します。
ent の UUID 型は、driver.Valuer Interface を利用して値を取得しますが、 oklog/ulid の Value()
の実装がバイナリを返却するようになっているため、このままでは可読性が悪いです。 Value()
が String を返すようにした ULID 型を新たに定義するのが良いでしょう。そのようにすると、他の interface も実装する必要があります。
結論から言うと https://github.com/ent/contrib/blob/6623819401500db45747a2419172963217cef619/entgql/internal/todopulid/ent/schema/pulid/pulid.go にそのものの実装があります1。この実装はライブラリ化されているものではない( internal )ので、そのままコピペして利用するのが良いでしょう。
使用する場合には以下のようになります。
// Fields of the User. func (User) Fields() []ent.Field { return []ent.Field{ field.String("id"). GoType(pulid.ID("")). DefaultFunc(func() pulid.ID { return pulid.MustNew("US") }), field.Int("age").Positive(), field.String("name").Default("unknown"), } }
prefixが不要な場合はprefixの部分を削ってしまうのが良いかと思います。
このままの実装でもう少し手軽に書きたい場合は、同リポジトリに mixin が存在しますので、これを持ち出すと良いと思います。
ent は各フィールドを固有の型にできますので、例えば上記例で ID を UserID
型にしたい場合は以下のようになります。
type UserID pulid.ID // Fields of the User. func (User) Fields() []ent.Field { return []ent.Field{ field.String("id"). GoType(UserID("")). DefaultFunc(func() UserID { return UserID(pulid.MustNew("US")) }), field.Int("age").Positive(), field.String("name").Default("unknown"), } }
-
https://github.com/tmc/pulid のように見えるのですが、こちらは
Value()
はバイナリを返すようです。↩