Skip to content

Commit

Permalink
add AllowClientUUIDs for client UUIDs in POSTs (#541)
Browse files Browse the repository at this point in the history
  • Loading branch information
bartke authored Sep 21, 2023
1 parent e38dfb6 commit 58da6fd
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 6 deletions.
13 changes: 13 additions & 0 deletions entoas/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ type (
// By enabling she SimpleModels configuration the generator simply adds the defined schemas with all fields and edges.
// Serialization groups have no effects in this mode.
SimpleModels bool
// When enabled, allows the built-in "id" field as part of the POST payload for entity creation, allowing the client to supply UUIDs as primary keys and for idempotency.
// Defaults to false.
AllowClientUUIDs bool
// Specify the minimum amount of itemsPerPage allowed in generated pagination.
// Defaults to 1.
MinItemsPerPage int64
Expand Down Expand Up @@ -134,6 +137,16 @@ func SimpleModels() ExtensionOption {
}
}

// AllowClientUUIDs enables the client supplied IDs feature.
//
// Further information can be found at Config.AllowClientUUIDs.
func AllowClientUUIDs() ExtensionOption {
return func(ex *Extension) error {
ex.config.AllowClientUUIDs = true
return nil
}
}

// WriteTo writes the current specs content to the given io.Writer.
func WriteTo(out io.Writer) ExtensionOption {
return func(ex *Extension) error {
Expand Down
27 changes: 21 additions & 6 deletions entoas/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"strings"

"entgo.io/ent/entc/gen"
"entgo.io/ent/schema/field"
"github.com/go-openapi/inflect"
"github.com/ogen-go/ogen"
"github.com/stoewer/go-strcase"
Expand Down Expand Up @@ -181,6 +182,11 @@ var rules = inflect.NewDefaultRuleset()

// paths adds all operations to the spec paths.
func paths(g *gen.Graph, spec *ogen.Spec) error {
cfg, err := GetConfig(g.Config)
if err != nil {
return err
}

for _, n := range g.Nodes {
// Add schema operations.
ops, err := NodeOperations(n)
Expand All @@ -191,7 +197,7 @@ func paths(g *gen.Graph, spec *ogen.Spec) error {
root := "/" + rules.Pluralize(strcase.KebabCase(n.Name))
// Create operation.
if contains(ops, OpCreate) {
path(spec, root).Post, err = createOp(spec, n)
path(spec, root).Post, err = createOp(spec, n, cfg.AllowClientUUIDs)
if err != nil {
return err
}
Expand Down Expand Up @@ -262,8 +268,8 @@ func path(s *ogen.Spec, root string) *ogen.PathItem {
}

// createOp returns an ogen.Operation for a create operation on the given node.
func createOp(spec *ogen.Spec, n *gen.Type) (*ogen.Operation, error) {
req, err := reqBody(n, OpCreate)
func createOp(spec *ogen.Spec, n *gen.Type, allowClientUUIDs bool) (*ogen.Operation, error) {
req, err := reqBody(n, OpCreate, allowClientUUIDs)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -358,7 +364,7 @@ func readEdgeOp(spec *ogen.Spec, n *gen.Type, e *gen.Edge) (*ogen.Operation, err

// updateOp returns a spec.OperationConfig for an update operation on the given node.
func updateOp(spec *ogen.Spec, n *gen.Type) (*ogen.Operation, error) {
req, err := reqBody(n, OpUpdate)
req, err := reqBody(n, OpUpdate, false)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -677,17 +683,26 @@ func EdgeOperations(e *gen.Edge) ([]Operation, error) {
}

// reqBody returns the request body for the given node and operation.
func reqBody(n *gen.Type, op Operation) (*ogen.RequestBody, error) {
func reqBody(n *gen.Type, op Operation, allowClientUUIDs bool) (*ogen.RequestBody, error) {
req := ogen.NewRequestBody().SetRequired(true)
c := ogen.NewSchema()
switch op {
case OpCreate:
// add the ID field as client setable if it is a UUID.
if allowClientUUIDs && n.ID.Type.Type == field.TypeUUID {
p, err := property(n.ID)
if err != nil {
return nil, err
}
addProperty(c, p, !n.ID.Default)
}

req.SetDescription(fmt.Sprintf("%s to create", n.Name))
case OpUpdate:
req.SetDescription(fmt.Sprintf("%s properties to update", n.Name))
default:
return nil, fmt.Errorf("requestBody: unsupported operation %q", op)
}
c := ogen.NewSchema()
for _, f := range n.Fields {
a, err := FieldAnnotation(f)
if err != nil {
Expand Down

0 comments on commit 58da6fd

Please sign in to comment.