graphql: fix knot in the graphql/gqlgen usage

Michael Muré created

Change summary

.gitignore                 |  1 +
graphql/gqlgen.yml         |  8 ++------
graphql/graph/gen_graph.go | 36 ++++++++++++++++++------------------
graphql/handler.go         |  5 +++--
graphql/models/models.go   |  8 ++++++++
graphql/resolvers/bug.go   |  5 +----
graphql/resolvers/query.go | 17 +++++++++--------
graphql/resolvers/repo.go  | 16 ++++++----------
graphql/resolvers/root.go  | 31 ++++++++++++++-----------------
9 files changed, 62 insertions(+), 65 deletions(-)

Detailed changes

.gitignore 🔗

@@ -1,3 +1,4 @@
 git-bug
 !/doc/bash_completion/git-bug
 !/doc/zsh_completion/git-bug
+.gitkeep

graphql/gqlgen.yml 🔗

@@ -1,16 +1,12 @@
 schema: schema.graphql
 exec:
-  filename: resolvers/gen_graph.go
+  filename: graph/gen_graph.go
 model:
   filename: models/gen_models.go
 
 models:
-  # Hack: here, we define the Repository model as a struct we control to trick gqlgen into
-  # generating an empty resolver instead of a struct with data
-  # Hopefully in the future, gqlgen support this case and we can clean that, as well as
-  # moving gen_graph.go into it's own package
   Repository:
-    model: github.com/MichaelMure/git-bug/graphql/resolvers.repoResolver
+    model: github.com/MichaelMure/git-bug/graphql/models.Repository
   Bug:
     model: github.com/MichaelMure/git-bug/bug.Snapshot
   Comment:

graphql/resolvers/gen_graph.go → graphql/graph/gen_graph.go 🔗

@@ -1,6 +1,6 @@
 // Code generated by github.com/vektah/gqlgen, DO NOT EDIT.
 
-package resolvers
+package graph
 
 import (
 	"bytes"
@@ -40,11 +40,11 @@ type Resolvers interface {
 
 	LabelChangeOperation_date(ctx context.Context, obj *operations.LabelChangeOperation) (time.Time, error)
 
-	Query_defaultRepository(ctx context.Context) (*repoResolver, error)
-	Query_repository(ctx context.Context, id string) (*repoResolver, error)
+	Query_defaultRepository(ctx context.Context) (*models.Repository, error)
+	Query_repository(ctx context.Context, id string) (*models.Repository, error)
 
-	Repository_allBugs(ctx context.Context, obj *repoResolver, input models.ConnectionInput) (models.BugConnection, error)
-	Repository_bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error)
+	Repository_allBugs(ctx context.Context, obj *models.Repository, input models.ConnectionInput) (models.BugConnection, error)
+	Repository_bug(ctx context.Context, obj *models.Repository, prefix string) (*bug.Snapshot, error)
 
 	SetStatusOperation_date(ctx context.Context, obj *operations.SetStatusOperation) (time.Time, error)
 	SetStatusOperation_status(ctx context.Context, obj *operations.SetStatusOperation) (models.Status, error)
@@ -78,12 +78,12 @@ type LabelChangeOperationResolver interface {
 	Date(ctx context.Context, obj *operations.LabelChangeOperation) (time.Time, error)
 }
 type QueryResolver interface {
-	DefaultRepository(ctx context.Context) (*repoResolver, error)
-	Repository(ctx context.Context, id string) (*repoResolver, error)
+	DefaultRepository(ctx context.Context) (*models.Repository, error)
+	Repository(ctx context.Context, id string) (*models.Repository, error)
 }
 type RepositoryResolver interface {
-	AllBugs(ctx context.Context, obj *repoResolver, input models.ConnectionInput) (models.BugConnection, error)
-	Bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error)
+	AllBugs(ctx context.Context, obj *models.Repository, input models.ConnectionInput) (models.BugConnection, error)
+	Bug(ctx context.Context, obj *models.Repository, prefix string) (*bug.Snapshot, error)
 }
 type SetStatusOperationResolver interface {
 	Date(ctx context.Context, obj *operations.SetStatusOperation) (time.Time, error)
@@ -121,19 +121,19 @@ func (s shortMapper) LabelChangeOperation_date(ctx context.Context, obj *operati
 	return s.r.LabelChangeOperation().Date(ctx, obj)
 }
 
-func (s shortMapper) Query_defaultRepository(ctx context.Context) (*repoResolver, error) {
+func (s shortMapper) Query_defaultRepository(ctx context.Context) (*models.Repository, error) {
 	return s.r.Query().DefaultRepository(ctx)
 }
 
-func (s shortMapper) Query_repository(ctx context.Context, id string) (*repoResolver, error) {
+func (s shortMapper) Query_repository(ctx context.Context, id string) (*models.Repository, error) {
 	return s.r.Query().Repository(ctx, id)
 }
 
-func (s shortMapper) Repository_allBugs(ctx context.Context, obj *repoResolver, input models.ConnectionInput) (models.BugConnection, error) {
+func (s shortMapper) Repository_allBugs(ctx context.Context, obj *models.Repository, input models.ConnectionInput) (models.BugConnection, error) {
 	return s.r.Repository().AllBugs(ctx, obj, input)
 }
 
-func (s shortMapper) Repository_bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error) {
+func (s shortMapper) Repository_bug(ctx context.Context, obj *models.Repository, prefix string) (*bug.Snapshot, error) {
 	return s.r.Repository().Bug(ctx, obj, prefix)
 }
 
@@ -1215,7 +1215,7 @@ func (ec *executionContext) _Query_defaultRepository(ctx context.Context, field
 		if resTmp == nil {
 			return graphql.Null
 		}
-		res := resTmp.(*repoResolver)
+		res := resTmp.(*models.Repository)
 		if res == nil {
 			return graphql.Null
 		}
@@ -1259,7 +1259,7 @@ func (ec *executionContext) _Query_repository(ctx context.Context, field graphql
 		if resTmp == nil {
 			return graphql.Null
 		}
-		res := resTmp.(*repoResolver)
+		res := resTmp.(*models.Repository)
 		if res == nil {
 			return graphql.Null
 		}
@@ -1309,7 +1309,7 @@ func (ec *executionContext) _Query___type(ctx context.Context, field graphql.Col
 var repositoryImplementors = []string{"Repository"}
 
 // nolint: gocyclo, errcheck, gas, goconst
-func (ec *executionContext) _Repository(ctx context.Context, sel []query.Selection, obj *repoResolver) graphql.Marshaler {
+func (ec *executionContext) _Repository(ctx context.Context, sel []query.Selection, obj *models.Repository) graphql.Marshaler {
 	fields := graphql.CollectFields(ec.Doc, sel, repositoryImplementors, ec.Variables)
 
 	out := graphql.NewOrderedMap(len(fields))
@@ -1331,7 +1331,7 @@ func (ec *executionContext) _Repository(ctx context.Context, sel []query.Selecti
 	return out
 }
 
-func (ec *executionContext) _Repository_allBugs(ctx context.Context, field graphql.CollectedField, obj *repoResolver) graphql.Marshaler {
+func (ec *executionContext) _Repository_allBugs(ctx context.Context, field graphql.CollectedField, obj *models.Repository) graphql.Marshaler {
 	args := map[string]interface{}{}
 	var arg0 models.ConnectionInput
 	if tmp, ok := field.Args["input"]; ok {
@@ -1372,7 +1372,7 @@ func (ec *executionContext) _Repository_allBugs(ctx context.Context, field graph
 	})
 }
 
-func (ec *executionContext) _Repository_bug(ctx context.Context, field graphql.CollectedField, obj *repoResolver) graphql.Marshaler {
+func (ec *executionContext) _Repository_bug(ctx context.Context, field graphql.CollectedField, obj *models.Repository) graphql.Marshaler {
 	args := map[string]interface{}{}
 	var arg0 string
 	if tmp, ok := field.Args["prefix"]; ok {

graphql/handler.go 🔗

@@ -3,6 +3,7 @@
 package graphql
 
 import (
+	"github.com/MichaelMure/git-bug/graphql/graph"
 	"github.com/MichaelMure/git-bug/graphql/resolvers"
 	"github.com/MichaelMure/git-bug/repository"
 	"github.com/vektah/gqlgen/handler"
@@ -10,9 +11,9 @@ import (
 )
 
 func NewHandler(repo repository.Repo) http.Handler {
-	backend := resolvers.NewRootResolver()
+	backend := resolvers.NewBackend()
 
 	backend.RegisterDefaultRepository(repo)
 
-	return handler.GraphQL(resolvers.NewExecutableSchema(backend))
+	return handler.GraphQL(graph.NewExecutableSchema(backend))
 }

graphql/models/models.go 🔗

@@ -0,0 +1,8 @@
+package models
+
+import "github.com/MichaelMure/git-bug/cache"
+
+type Repository struct {
+	Cache cache.Cacher
+	Repo  cache.RepoCacher
+}

graphql/resolvers/bug.go 🔗

@@ -3,14 +3,11 @@ package resolvers
 import (
 	"context"
 	"github.com/MichaelMure/git-bug/bug"
-	"github.com/MichaelMure/git-bug/cache"
 	"github.com/MichaelMure/git-bug/graphql/connections"
 	"github.com/MichaelMure/git-bug/graphql/models"
 )
 
-type bugResolver struct {
-	cache cache.Cacher
-}
+type bugResolver struct{}
 
 func (bugResolver) Status(ctx context.Context, obj *bug.Snapshot) (models.Status, error) {
 	return convertStatus(obj.Status)

graphql/resolvers/query.go 🔗

@@ -3,34 +3,35 @@ package resolvers
 import (
 	"context"
 	"github.com/MichaelMure/git-bug/cache"
+	"github.com/MichaelMure/git-bug/graphql/models"
 )
 
 type rootQueryResolver struct {
 	cache cache.Cacher
 }
 
-func (r rootQueryResolver) DefaultRepository(ctx context.Context) (*repoResolver, error) {
+func (r rootQueryResolver) DefaultRepository(ctx context.Context) (*models.Repository, error) {
 	repo, err := r.cache.DefaultRepo()
 
 	if err != nil {
 		return nil, err
 	}
 
-	return &repoResolver{
-		cache: r.cache,
-		repo:  repo,
+	return &models.Repository{
+		Cache: r.cache,
+		Repo:  repo,
 	}, nil
 }
 
-func (r rootQueryResolver) Repository(ctx context.Context, id string) (*repoResolver, error) {
+func (r rootQueryResolver) Repository(ctx context.Context, id string) (*models.Repository, error) {
 	repo, err := r.cache.ResolveRepo(id)
 
 	if err != nil {
 		return nil, err
 	}
 
-	return &repoResolver{
-		cache: r.cache,
-		repo:  repo,
+	return &models.Repository{
+		Cache: r.cache,
+		Repo:  repo,
 	}, nil
 }

graphql/resolvers/repo.go 🔗

@@ -3,20 +3,16 @@ package resolvers
 import (
 	"context"
 	"github.com/MichaelMure/git-bug/bug"
-	"github.com/MichaelMure/git-bug/cache"
 	"github.com/MichaelMure/git-bug/graphql/connections"
 	"github.com/MichaelMure/git-bug/graphql/models"
 )
 
-type repoResolver struct {
-	cache cache.Cacher
-	repo  cache.RepoCacher
-}
+type repoResolver struct{}
 
-func (repoResolver) AllBugs(ctx context.Context, obj *repoResolver, input models.ConnectionInput) (models.BugConnection, error) {
+func (repoResolver) AllBugs(ctx context.Context, obj *models.Repository, input models.ConnectionInput) (models.BugConnection, error) {
 
 	// Simply pass a []string with the ids to the pagination algorithm
-	source, err := obj.repo.AllBugIds()
+	source, err := obj.Repo.AllBugIds()
 
 	if err != nil {
 		return models.BugConnection{}, err
@@ -35,7 +31,7 @@ func (repoResolver) AllBugs(ctx context.Context, obj *repoResolver, input models
 		edges := make([]models.BugEdge, len(lazyBugEdges))
 
 		for i, lazyBugEdge := range lazyBugEdges {
-			b, err := obj.repo.ResolveBug(lazyBugEdge.Id)
+			b, err := obj.Repo.ResolveBug(lazyBugEdge.Id)
 
 			if err != nil {
 				return models.BugConnection{}, err
@@ -59,8 +55,8 @@ func (repoResolver) AllBugs(ctx context.Context, obj *repoResolver, input models
 	return connections.StringCon(source, edger, conMaker, input)
 }
 
-func (repoResolver) Bug(ctx context.Context, obj *repoResolver, prefix string) (*bug.Snapshot, error) {
-	b, err := obj.repo.ResolveBugPrefix(prefix)
+func (repoResolver) Bug(ctx context.Context, obj *models.Repository, prefix string) (*bug.Snapshot, error) {
+	b, err := obj.Repo.ResolveBugPrefix(prefix)
 
 	if err != nil {
 		return nil, err

graphql/resolvers/root.go 🔗

@@ -2,52 +2,49 @@ package resolvers
 
 import (
 	"github.com/MichaelMure/git-bug/cache"
+	"github.com/MichaelMure/git-bug/graphql/graph"
 )
 
-type RootResolver struct {
+type Backend struct {
 	cache.RootCache
 }
 
-func NewRootResolver() *RootResolver {
-	return &RootResolver{
+func NewBackend() *Backend {
+	return &Backend{
 		RootCache: cache.NewCache(),
 	}
 }
 
-func (r RootResolver) Query() QueryResolver {
+func (r Backend) Query() graph.QueryResolver {
 	return &rootQueryResolver{
 		cache: &r.RootCache,
 	}
 }
 
-func (RootResolver) AddCommentOperation() AddCommentOperationResolver {
+func (Backend) AddCommentOperation() graph.AddCommentOperationResolver {
 	return &addCommentOperationResolver{}
 }
 
-func (r RootResolver) Bug() BugResolver {
-	return &bugResolver{
-		cache: &r.RootCache,
-	}
+func (r Backend) Bug() graph.BugResolver {
+	return &bugResolver{}
 }
 
-func (RootResolver) CreateOperation() CreateOperationResolver {
+func (Backend) CreateOperation() graph.CreateOperationResolver {
 	return &createOperationResolver{}
 }
 
-func (RootResolver) LabelChangeOperation() LabelChangeOperationResolver {
+func (Backend) LabelChangeOperation() graph.LabelChangeOperationResolver {
 	return &labelChangeOperation{}
 }
 
-func (r RootResolver) Repository() RepositoryResolver {
-	return &repoResolver{
-		cache: &r.RootCache,
-	}
+func (r Backend) Repository() graph.RepositoryResolver {
+	return &repoResolver{}
 }
 
-func (RootResolver) SetStatusOperation() SetStatusOperationResolver {
+func (Backend) SetStatusOperation() graph.SetStatusOperationResolver {
 	return &setStatusOperationResolver{}
 }
 
-func (RootResolver) SetTitleOperation() SetTitleOperationResolver {
+func (Backend) SetTitleOperation() graph.SetTitleOperationResolver {
 	return &setTitleOperationResolver{}
 }