From 911df36eb27a5dadc7770c5646ff69d514cf8385 Mon Sep 17 00:00:00 2001 From: gilex-dev Date: Fri, 1 Sep 2023 21:33:26 +0200 Subject: [PATCH] follow "gqlgen getting started" --- gqlgen.yml | 6 ++++- graph/generated.go | 57 ++++++++++++++++++++++++++++++++------- graph/model/models_gen.go | 7 ----- graph/model/todo.go | 8 ++++++ graph/resolver.go | 8 +++++- graph/schema.resolvers.go | 23 +++++++++++++--- 6 files changed, 88 insertions(+), 21 deletions(-) create mode 100644 graph/model/todo.go diff --git a/gqlgen.yml b/gqlgen.yml index f113a11..40af64d 100644 --- a/gqlgen.yml +++ b/gqlgen.yml @@ -81,7 +81,7 @@ resolver: # gqlgen will search for any type names in the schema in these go packages # if they match it will use them, otherwise it will generate them. autobind: -# - "somepi.ddns.net/gitea/gilex-dev/YetAnotherToDoList/graph/model" + - "somepi.ddns.net/gitea/gilex-dev/YetAnotherToDoList/graph/model" # This section declares type mapping between the GraphQL and go type systems # @@ -100,3 +100,7 @@ models: - github.com/99designs/gqlgen/graphql.Int - github.com/99designs/gqlgen/graphql.Int64 - github.com/99designs/gqlgen/graphql.Int32 + Todo: + fields: + user: + resolver: true diff --git a/graph/generated.go b/graph/generated.go index e3a9077..931fc74 100644 --- a/graph/generated.go +++ b/graph/generated.go @@ -39,6 +39,7 @@ type Config struct { type ResolverRoot interface { Mutation() MutationResolver Query() QueryResolver + Todo() TodoResolver } type DirectiveRoot struct { @@ -72,6 +73,9 @@ type MutationResolver interface { type QueryResolver interface { Todos(ctx context.Context) ([]*model.Todo, error) } +type TodoResolver interface { + User(ctx context.Context, obj *model.Todo) (*model.User, error) +} type executableSchema struct { resolvers ResolverRoot @@ -736,7 +740,7 @@ func (ec *executionContext) _Todo_user(ctx context.Context, field graphql.Collec }() resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return obj.User, nil + return ec.resolvers.Todo().User(rctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -757,8 +761,8 @@ func (ec *executionContext) fieldContext_Todo_user(ctx context.Context, field gr fc = &graphql.FieldContext{ Object: "Todo", Field: field, - IsMethod: false, - IsResolver: false, + IsMethod: true, + IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "id": @@ -2814,23 +2818,54 @@ func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj case "id": out.Values[i] = ec._Todo_id(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "text": out.Values[i] = ec._Todo_text(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "done": out.Values[i] = ec._Todo_done(ctx, field, obj) if out.Values[i] == graphql.Null { - out.Invalids++ + atomic.AddUint32(&out.Invalids, 1) } case "user": - out.Values[i] = ec._Todo_user(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Todo_user(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3332,6 +3367,10 @@ func (ec *executionContext) marshalNTodo2ᚖsomepiᚗddnsᚗnetᚋgiteaᚋgilex return ec._Todo(ctx, sel, v) } +func (ec *executionContext) marshalNUser2somepiᚗddnsᚗnetᚋgiteaᚋgilexᚑdevᚋYetAnotherToDoListᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v model.User) graphql.Marshaler { + return ec._User(ctx, sel, &v) +} + func (ec *executionContext) marshalNUser2ᚖsomepiᚗddnsᚗnetᚋgiteaᚋgilexᚑdevᚋYetAnotherToDoListᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v *model.User) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { diff --git a/graph/model/models_gen.go b/graph/model/models_gen.go index 70ebe4f..bd3d473 100644 --- a/graph/model/models_gen.go +++ b/graph/model/models_gen.go @@ -7,13 +7,6 @@ type NewTodo struct { UserID string `json:"userId"` } -type Todo struct { - ID string `json:"id"` - Text string `json:"text"` - Done bool `json:"done"` - User *User `json:"user"` -} - type User struct { ID string `json:"id"` Name string `json:"name"` diff --git a/graph/model/todo.go b/graph/model/todo.go new file mode 100644 index 0000000..ece76b0 --- /dev/null +++ b/graph/model/todo.go @@ -0,0 +1,8 @@ +package model + +type Todo struct { + ID string `json:"id"` + Text string `json:"text"` + Done bool `json:"done"` + User *User `json:"user"` +} diff --git a/graph/resolver.go b/graph/resolver.go index ee2c6b4..e734407 100644 --- a/graph/resolver.go +++ b/graph/resolver.go @@ -16,8 +16,14 @@ along with this program. If not, see . */ package graph +//go:generate go run github.com/99designs/gqlgen generate +import "somepi.ddns.net/gitea/gilex-dev/YetAnotherToDoList/graph/model" + // This file will not be regenerated automatically. // // It serves as dependency injection for your app, add any dependencies you require here. -type Resolver struct{} +type Resolver struct { + todos []*model.Todo + getUser *model.User +} diff --git a/graph/schema.resolvers.go b/graph/schema.resolvers.go index 5a5b176..f84cfa9 100644 --- a/graph/schema.resolvers.go +++ b/graph/schema.resolvers.go @@ -6,19 +6,32 @@ package graph import ( "context" - "fmt" + "crypto/rand" + "math/big" "somepi.ddns.net/gitea/gilex-dev/YetAnotherToDoList/graph/model" ) // CreateTodo is the resolver for the createTodo field. func (r *mutationResolver) CreateTodo(ctx context.Context, input model.NewTodo) (*model.Todo, error) { - panic(fmt.Errorf("not implemented: CreateTodo - createTodo")) + rand, _ := rand.Int(rand.Reader, big.NewInt(100)) + todo := &model.Todo{ + ID: rand.String(), + Text: input.Text, + User: &model.User{ID: input.UserID, Name: "User-" + input.UserID}, + } + r.todos = append(r.todos, todo) + return todo, nil } // Todos is the resolver for the todos field. func (r *queryResolver) Todos(ctx context.Context) ([]*model.Todo, error) { - panic(fmt.Errorf("not implemented: Todos - todos")) + return r.todos, nil +} + +// User is the resolver for the user field. +func (r *todoResolver) User(ctx context.Context, obj *model.Todo) (*model.User, error) { + return &model.User{ID: obj.User.ID, Name: obj.User.Name}, nil } // Mutation returns MutationResolver implementation. @@ -27,5 +40,9 @@ func (r *Resolver) Mutation() MutationResolver { return &mutationResolver{r} } // Query returns QueryResolver implementation. func (r *Resolver) Query() QueryResolver { return &queryResolver{r} } +// Todo returns TodoResolver implementation. +func (r *Resolver) Todo() TodoResolver { return &todoResolver{r} } + type mutationResolver struct{ *Resolver } type queryResolver struct{ *Resolver } +type todoResolver struct{ *Resolver }