Skip to content

Commit

Permalink
Always return *Thing from resolvers for structs
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Scarr committed Feb 18, 2019
1 parent ef0223c commit 318639b
Show file tree
Hide file tree
Showing 23 changed files with 176 additions and 65 deletions.
18 changes: 18 additions & 0 deletions codegen/config/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,19 @@ func (b *Binder) FindObject(pkgName string, typeName string) (types.Object, erro
return nil, errors.Errorf("unable to find type %s\n", fullName)
}

func (b *Binder) PointerTo(ref *TypeReference) *TypeReference {
newRef := &TypeReference{
GO: types.NewPointer(ref.GO),
GQL: ref.GQL,
Definition: ref.Definition,
Unmarshaler: ref.Unmarshaler,
Marshaler: ref.Marshaler,
}

b.References = append(b.References, newRef)
return newRef
}

var modsRegex = regexp.MustCompile(`^(\*|\[\])*`)

func normalizeVendor(pkg string) string {
Expand Down Expand Up @@ -205,6 +218,11 @@ func (t *TypeReference) IsNamed() bool {
return isSlice
}

func (t *TypeReference) IsStruct() bool {
_, isStruct := t.GO.Underlying().(*types.Struct)
return isStruct
}

func (t *TypeReference) IsScalar() bool {
return t.Definition.Kind == ast.Scalar
}
Expand Down
5 changes: 5 additions & 0 deletions codegen/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,12 @@ func (b *builder) bindField(obj *Object, f *Field) error {
}
f.TypeReference = tr
}

if f.IsResolver && !f.TypeReference.IsPtr() && f.TypeReference.IsStruct() {
f.TypeReference = b.Binder.PointerTo(f.TypeReference)
}
}()

switch {
case f.Name == "__schema":
f.GoFieldType = GoFieldMethod
Expand Down
16 changes: 13 additions & 3 deletions codegen/testserver/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions codegen/testserver/middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ func TestMiddleware(t *testing.T) {
return &Error{ID: "E1234"}, nil
}

resolvers.QueryResolver.User = func(ctx context.Context, id int) (user User, e error) {
return User{ID: 1}, nil
resolvers.QueryResolver.User = func(ctx context.Context, id int) (user *User, e error) {
return &User{ID: 1}, nil
}

resolvers.UserResolver.Friends = func(ctx context.Context, obj *User) (users []User, e error) {
Expand Down
2 changes: 1 addition & 1 deletion codegen/testserver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func (r *queryResolver) ModelMethods(ctx context.Context) (*ModelMethods, error)
func (r *queryResolver) Valid(ctx context.Context) (string, error) {
panic("not implemented")
}
func (r *queryResolver) User(ctx context.Context, id int) (User, error) {
func (r *queryResolver) User(ctx context.Context, id int) (*User, error) {
panic("not implemented")
}
func (r *queryResolver) NullableArg(ctx context.Context, arg *int) (*string, error) {
Expand Down
4 changes: 2 additions & 2 deletions codegen/testserver/stub.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions codegen/testserver/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ func TestTime(t *testing.T) {
srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(Config{Resolvers: resolvers})))
c := client.New(srv.URL)

resolvers.QueryResolver.User = func(ctx context.Context, id int) (user User, e error) {
return User{}, nil
resolvers.QueryResolver.User = func(ctx context.Context, id int) (user *User, e error) {
return &User{}, nil
}

t.Run("zero value in nullable field", func(t *testing.T) {
Expand Down Expand Up @@ -46,9 +46,9 @@ func TestTime(t *testing.T) {
})

t.Run("with values", func(t *testing.T) {
resolvers.QueryResolver.User = func(ctx context.Context, id int) (user User, e error) {
resolvers.QueryResolver.User = func(ctx context.Context, id int) (user *User, e error) {
updated := time.Date(2010, 1, 1, 0, 0, 20, 0, time.UTC)
return User{
return &User{
Created: time.Date(2010, 1, 1, 0, 0, 10, 0, time.UTC),
Updated: &updated,
}, nil
Expand Down
4 changes: 2 additions & 2 deletions codegen/testserver/tracer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import (

func TestTracer(t *testing.T) {
resolvers := &Stub{}
resolvers.QueryResolver.User = func(ctx context.Context, id int) (user User, e error) {
return User{ID: 1}, nil
resolvers.QueryResolver.User = func(ctx context.Context, id int) (user *User, e error) {
return &User{ID: 1}, nil
}
t.Run("called in the correct order", func(t *testing.T) {
var tracerLog []string
Expand Down
20 changes: 15 additions & 5 deletions example/chat/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 9 additions & 9 deletions example/chat/resolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ func New() Config {
type Chatroom struct {
Name string
Messages []Message
Observers map[string]chan Message
Observers map[string]chan *Message
}

type mutationResolver struct{ *resolver }

func (r *mutationResolver) Post(ctx context.Context, text string, username string, roomName string) (Message, error) {
func (r *mutationResolver) Post(ctx context.Context, text string, username string, roomName string) (*Message, error) {
r.mu.Lock()
room := r.Rooms[roomName]
if room == nil {
room = &Chatroom{Name: roomName, Observers: map[string]chan Message{}}
room = &Chatroom{Name: roomName, Observers: map[string]chan *Message{}}
r.Rooms[roomName] = room
}
r.mu.Unlock()
Expand All @@ -61,10 +61,10 @@ func (r *mutationResolver) Post(ctx context.Context, text string, username strin
room.Messages = append(room.Messages, message)
r.mu.Lock()
for _, observer := range room.Observers {
observer <- message
observer <- &message
}
r.mu.Unlock()
return message, nil
return &message, nil
}

type queryResolver struct{ *resolver }
Expand All @@ -73,7 +73,7 @@ func (r *queryResolver) Room(ctx context.Context, name string) (*Chatroom, error
r.mu.Lock()
room := r.Rooms[name]
if room == nil {
room = &Chatroom{Name: name, Observers: map[string]chan Message{}}
room = &Chatroom{Name: name, Observers: map[string]chan *Message{}}
r.Rooms[name] = room
}
r.mu.Unlock()
Expand All @@ -83,17 +83,17 @@ func (r *queryResolver) Room(ctx context.Context, name string) (*Chatroom, error

type subscriptionResolver struct{ *resolver }

func (r *subscriptionResolver) MessageAdded(ctx context.Context, roomName string) (<-chan Message, error) {
func (r *subscriptionResolver) MessageAdded(ctx context.Context, roomName string) (<-chan *Message, error) {
r.mu.Lock()
room := r.Rooms[roomName]
if room == nil {
room = &Chatroom{Name: roomName, Observers: map[string]chan Message{}}
room = &Chatroom{Name: roomName, Observers: map[string]chan *Message{}}
r.Rooms[roomName] = room
}
r.mu.Unlock()

id := randString(8)
events := make(chan Message, 1)
events := make(chan *Message, 1)

go func() {
<-ctx.Done()
Expand Down
16 changes: 13 additions & 3 deletions example/config/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions example/config/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func (r *Resolver) Todo() TodoResolver {

type mutationResolver struct{ *Resolver }

func (r *mutationResolver) CreateTodo(ctx context.Context, input NewTodo) (Todo, error) {
func (r *mutationResolver) CreateTodo(ctx context.Context, input NewTodo) (*Todo, error) {
newID := r.nextID
r.nextID++

Expand All @@ -49,7 +49,7 @@ func (r *mutationResolver) CreateTodo(ctx context.Context, input NewTodo) (Todo,

r.todos = append(r.todos, newTodo)

return newTodo, nil
return &newTodo, nil
}

type queryResolver struct{ *Resolver }
Expand Down
24 changes: 21 additions & 3 deletions example/scalars/generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions example/scalars/resolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ func (r *userResolver) PrimitiveResolver(ctx context.Context, obj *model.User) (
return "test", nil
}

func (r *userResolver) CustomResolver(ctx context.Context, obj *model.User) (model.Point, error) {
return model.Point{X: 5, Y: 1}, nil
func (r *userResolver) CustomResolver(ctx context.Context, obj *model.User) (*model.Point, error) {
return &model.Point{X: 5, Y: 1}, nil
}
Loading

0 comments on commit 318639b

Please sign in to comment.