Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement AllowClientUUIDs for record creation #241

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ type (
Target string
// The Views created by entoas.
Views map[string]*entoas.View
// Whether to allow the client to supply IDs in case uuids are used.
// AllowClientUUIDs, when enabled, allows the built-in "id" field as part of the payload for create, allowing the client to supply UUIDs as primary keys and for idempotency.
AllowClientUUIDs bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about making it more generic and allow to set any ID field, if given?

}
// Extension implements entc.Extension interface providing integration with ogen.
Extension struct {
Expand All @@ -41,12 +44,14 @@ func NewExtension(spec *ogen.Spec, opts ...ExtensionOption) (*Extension, error)
if spec == nil {
return nil, errors.New("ogent: spec cannot be nil")
}
ex := &Extension{spec: spec, cfg: new(Config), templates: []*gen.Template{templates}}
ex := &Extension{spec: spec, cfg: new(Config)}
for _, opt := range opts {
if err := opt(ex); err != nil {
return nil, err
}
}
ex.templates = []*gen.Template{genTemplates(ex.cfg)}

return ex, nil
}

Expand All @@ -58,6 +63,14 @@ func Target(t string) ExtensionOption {
}
}

// AllowClientUUIDs allows the client to supply IDs in case uuids are used.
func AllowClientUUIDs() ExtensionOption {
return func(ex *Extension) error {
ex.cfg.AllowClientUUIDs = true
return nil
}
}

// Templates adds the given templates to the code generator.
func Templates(ts ...*gen.Template) ExtensionOption {
return func(ex *Extension) error {
Expand Down
15 changes: 11 additions & 4 deletions template.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ import (
var (
//go:embed template
templateDir embed.FS
)

func genTemplates(cfg *Config) *gen.Template {
// funcMap contains extra template functions used by ogent.
funcMap = template.FuncMap{
funcMap := template.FuncMap{
"allowClientUUIDs": func() bool {
return cfg.AllowClientUUIDs
},
Comment on lines +26 to +28
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of this I prefer to use extend and add the flag there. Have a look at how it is done inside Ent: https://github.com/ent/ent/blob/3f1063c77ec98d1b1d5d1cdc39659cd13931ab8f/entc/gen/func.go#L265

"convertTo": convertTo,
"eagerLoad": eagerLoad,
"edgeOperations": entoas.EdgeOperations,
Expand All @@ -43,8 +49,9 @@ var (
"viewNameEdge": entoas.ViewNameEdge,
}
// templates holds all templates used by ogent.
templates = gen.MustParse(gen.NewTemplate("ogent").Funcs(funcMap).ParseFS(templateDir, "template/*tmpl"))
)
templates := gen.MustParse(gen.NewTemplate("ogent").Funcs(funcMap).ParseFS(templateDir, "template/*tmpl"))
return templates
}

// eagerLoad returns the Go expression to eager load the required edges on the node operation.
func eagerLoad(n *gen.Type, op entoas.Operation) (string, error) {
Expand Down Expand Up @@ -237,7 +244,7 @@ func setFieldExpr(f *gen.Field, schema, rec, ident string) (string, error) {
case Date:
opt = "Date"
case Time:
opt = "Time"
opt = "Time"
case Duration:
opt = "Duration"
case UUID:
Expand Down
7 changes: 7 additions & 0 deletions template/create.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
{{ define "ogent/ogent/helper/create" }}{{/* gotype: entgo.io/ent/entc/gen.Type */}}
b := h.client.{{ $.Name }}.Create()
{{ if allowClientUUIDs }}
{{ if eq $.ID.Type.Ident "uuid.UUID" }}
if v, ok := req.{{ $.ID.StructField }}.Get(); ok && v != uuid.Nil {
b.Set{{ $.ID.StructField }}(v)
}
{{ end }}
{{ end }}
// Add all fields.
{{- range $f := $.Fields }}
{{- $a := fieldAnnotation $f }}
Expand Down