From 5c04d1adaddd2b67b5052caa33488a4a2c011df0 Mon Sep 17 00:00:00 2001 From: Adam Scarr Date: Fri, 16 Feb 2018 14:02:35 +1100 Subject: [PATCH] __typename support --- example/dataloader/addressloader_gen.go | 19 +++++++++++--- example/dataloader/generated.go | 22 ++++++++++++++++ example/dataloader/itemsliceloader_gen.go | 19 +++++++++++--- example/dataloader/ordersliceloader_gen.go | 19 +++++++++++--- example/starwars/generated.go | 30 ++++++++++++++++++++++ example/starwars/starwars_test.go | 8 ++++-- example/todo/generated.go | 18 +++++++++++++ example/todo/todo_test.go | 11 ++++++++ templates/object.go | 2 ++ 9 files changed, 137 insertions(+), 11 deletions(-) diff --git a/example/dataloader/addressloader_gen.go b/example/dataloader/addressloader_gen.go index 2df27968e8..ffa2f6c944 100644 --- a/example/dataloader/addressloader_gen.go +++ b/example/dataloader/addressloader_gen.go @@ -65,16 +65,29 @@ func (l *AddressLoader) LoadThunk(key int) func() (*Address, error) { return func() (*Address, error) { <-batch.done - if batch.error[pos] == nil { + var data *Address + if pos < len(batch.data) { + data = batch.data[pos] + } + + var err error + // its convenient to be able to return a single error for everything + if len(batch.error) == 1 { + err = batch.error[pos] + } else if batch.error != nil { + err = batch.error[pos] + } + + if err == nil { l.mu.Lock() if l.cache == nil { l.cache = map[int]*Address{} } - l.cache[key] = batch.data[pos] + l.cache[key] = data l.mu.Unlock() } - return batch.data[pos], batch.error[pos] + return data, err } } diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index 69f0fc7d5a..2a2d6fe702 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -94,6 +94,8 @@ func (ec *executionContext) _address(sel []query.Selection, it *Address) jsonw.W out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Address") case "id": res := it.ID @@ -125,6 +127,8 @@ func (ec *executionContext) _customer(sel []query.Selection, it *Customer) jsonw out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Customer") case "id": res := it.ID @@ -186,6 +190,8 @@ func (ec *executionContext) _item(sel []query.Selection, it *Item) jsonw.Writer out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Item") case "name": res := it.Name @@ -209,6 +215,8 @@ func (ec *executionContext) _order(sel []query.Selection, it *Order) jsonw.Write out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Order") case "id": res := it.ID @@ -258,6 +266,8 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Query") case "customers": ec.wg.Add(1) go func(i int, field collectedField) { @@ -320,6 +330,8 @@ func (ec *executionContext) ___Directive(sel []query.Selection, it *introspectio out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Directive") case "name": res := it.Name() @@ -376,6 +388,8 @@ func (ec *executionContext) ___EnumValue(sel []query.Selection, it *introspectio out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__EnumValue") case "name": res := it.Name() @@ -419,6 +433,8 @@ func (ec *executionContext) ___Field(sel []query.Selection, it *introspection.Fi out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Field") case "name": res := it.Name() @@ -485,6 +501,8 @@ func (ec *executionContext) ___InputValue(sel []query.Selection, it *introspecti out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__InputValue") case "name": res := it.Name() @@ -532,6 +550,8 @@ func (ec *executionContext) ___Schema(sel []query.Selection, it *introspection.S out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Schema") case "types": res := it.Types() @@ -605,6 +625,8 @@ func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Typ out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Type") case "kind": res := it.Kind() diff --git a/example/dataloader/itemsliceloader_gen.go b/example/dataloader/itemsliceloader_gen.go index 430f432cc5..d71837d2cb 100644 --- a/example/dataloader/itemsliceloader_gen.go +++ b/example/dataloader/itemsliceloader_gen.go @@ -65,16 +65,29 @@ func (l *ItemSliceLoader) LoadThunk(key int) func() ([]Item, error) { return func() ([]Item, error) { <-batch.done - if batch.error[pos] == nil { + var data []Item + if pos < len(batch.data) { + data = batch.data[pos] + } + + var err error + // its convenient to be able to return a single error for everything + if len(batch.error) == 1 { + err = batch.error[pos] + } else if batch.error != nil { + err = batch.error[pos] + } + + if err == nil { l.mu.Lock() if l.cache == nil { l.cache = map[int][]Item{} } - l.cache[key] = batch.data[pos] + l.cache[key] = data l.mu.Unlock() } - return batch.data[pos], batch.error[pos] + return data, err } } diff --git a/example/dataloader/ordersliceloader_gen.go b/example/dataloader/ordersliceloader_gen.go index 9d88753485..e8f705d183 100644 --- a/example/dataloader/ordersliceloader_gen.go +++ b/example/dataloader/ordersliceloader_gen.go @@ -65,16 +65,29 @@ func (l *OrderSliceLoader) LoadThunk(key int) func() ([]Order, error) { return func() ([]Order, error) { <-batch.done - if batch.error[pos] == nil { + var data []Order + if pos < len(batch.data) { + data = batch.data[pos] + } + + var err error + // its convenient to be able to return a single error for everything + if len(batch.error) == 1 { + err = batch.error[pos] + } else if batch.error != nil { + err = batch.error[pos] + } + + if err == nil { l.mu.Lock() if l.cache == nil { l.cache = map[int][]Order{} } - l.cache[key] = batch.data[pos] + l.cache[key] = data l.mu.Unlock() } - return batch.data[pos], batch.error[pos] + return data, err } } diff --git a/example/starwars/generated.go b/example/starwars/generated.go index a2ba1e285b..6705acce03 100644 --- a/example/starwars/generated.go +++ b/example/starwars/generated.go @@ -110,6 +110,8 @@ func (ec *executionContext) _droid(sel []query.Selection, it *Droid) jsonw.Write out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Droid") case "id": res := it.ID @@ -199,6 +201,8 @@ func (ec *executionContext) _friendsConnection(sel []query.Selection, it *Friend out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("FriendsConnection") case "totalCount": res := it.TotalCount() @@ -262,6 +266,8 @@ func (ec *executionContext) _friendsEdge(sel []query.Selection, it *FriendsEdge) out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("FriendsEdge") case "cursor": res := it.Cursor @@ -289,6 +295,8 @@ func (ec *executionContext) _human(sel []query.Selection, it *Human) jsonw.Write out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Human") case "id": res := it.ID @@ -409,6 +417,8 @@ func (ec *executionContext) _mutation(sel []query.Selection, it *interface{}) js out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Mutation") case "createReview": var arg0 string if tmp, ok := field.Args["episode"]; ok { @@ -455,6 +465,8 @@ func (ec *executionContext) _pageInfo(sel []query.Selection, it *PageInfo) jsonw out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("PageInfo") case "startCursor": res := it.StartCursor @@ -486,6 +498,8 @@ func (ec *executionContext) _query(sel []query.Selection, it *interface{}) jsonw out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Query") case "hero": var arg0 *string if tmp, ok := field.Args["episode"]; ok { @@ -715,6 +729,8 @@ func (ec *executionContext) _review(sel []query.Selection, it *Review) jsonw.Wri out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Review") case "stars": res := it.Stars @@ -750,6 +766,8 @@ func (ec *executionContext) _starship(sel []query.Selection, it *Starship) jsonw out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Starship") case "id": res := it.ID @@ -807,6 +825,8 @@ func (ec *executionContext) ___Directive(sel []query.Selection, it *introspectio out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Directive") case "name": res := it.Name() @@ -863,6 +883,8 @@ func (ec *executionContext) ___EnumValue(sel []query.Selection, it *introspectio out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__EnumValue") case "name": res := it.Name() @@ -906,6 +928,8 @@ func (ec *executionContext) ___Field(sel []query.Selection, it *introspection.Fi out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Field") case "name": res := it.Name() @@ -972,6 +996,8 @@ func (ec *executionContext) ___InputValue(sel []query.Selection, it *introspecti out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__InputValue") case "name": res := it.Name() @@ -1019,6 +1045,8 @@ func (ec *executionContext) ___Schema(sel []query.Selection, it *introspection.S out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Schema") case "types": res := it.Types() @@ -1092,6 +1120,8 @@ func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Typ out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Type") case "kind": res := it.Kind() diff --git a/example/starwars/starwars_test.go b/example/starwars/starwars_test.go index 90944955b5..8ea53c7983 100644 --- a/example/starwars/starwars_test.go +++ b/example/starwars/starwars_test.go @@ -26,11 +26,15 @@ func TestStarwars(t *testing.T) { t.Run("get character", func(t *testing.T) { var resp struct { - Character struct{ Name string } + Character struct { + Name string + Typename string `json:"__typename"` + } } - c.MustPost(`{ character(id:2001) { name } }`, &resp) + c.MustPost(`{ character(id:2001) { name, __typename } }`, &resp) require.Equal(t, "R2-D2", resp.Character.Name) + require.Equal(t, "Droid", resp.Character.Typename) }) t.Run("missing character", func(t *testing.T) { diff --git a/example/todo/generated.go b/example/todo/generated.go index 2727fc3903..181bfe3926 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -96,6 +96,8 @@ func (ec *executionContext) _myMutation(sel []query.Selection, it *interface{}) out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("MyMutation") case "createTodo": var arg0 string if tmp, ok := field.Args["text"]; ok { @@ -157,6 +159,8 @@ func (ec *executionContext) _myQuery(sel []query.Selection, it *interface{}) jso out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("MyQuery") case "todo": var arg0 int if tmp, ok := field.Args["id"]; ok { @@ -260,6 +264,8 @@ func (ec *executionContext) _todo(sel []query.Selection, it *Todo) jsonw.Writer out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("Todo") case "id": res := it.ID() @@ -291,6 +297,8 @@ func (ec *executionContext) ___Directive(sel []query.Selection, it *introspectio out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Directive") case "name": res := it.Name() @@ -347,6 +355,8 @@ func (ec *executionContext) ___EnumValue(sel []query.Selection, it *introspectio out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__EnumValue") case "name": res := it.Name() @@ -390,6 +400,8 @@ func (ec *executionContext) ___Field(sel []query.Selection, it *introspection.Fi out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Field") case "name": res := it.Name() @@ -456,6 +468,8 @@ func (ec *executionContext) ___InputValue(sel []query.Selection, it *introspecti out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__InputValue") case "name": res := it.Name() @@ -503,6 +517,8 @@ func (ec *executionContext) ___Schema(sel []query.Selection, it *introspection.S out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Schema") case "types": res := it.Types() @@ -576,6 +592,8 @@ func (ec *executionContext) ___Type(sel []query.Selection, it *introspection.Typ out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String("__Type") case "kind": res := it.Kind() diff --git a/example/todo/todo_test.go b/example/todo/todo_test.go index 201ba1c123..de7e879374 100644 --- a/example/todo/todo_test.go +++ b/example/todo/todo_test.go @@ -33,6 +33,17 @@ func TestTodo(t *testing.T) { require.Equal(t, "Very important", resp.UpdateTodo.Text) }) + t.Run("get __typename", func(t *testing.T) { + var resp struct { + Todo struct { + Typename string `json:"__typename"` + } + } + c.MustPost(`{ todo(id: 4) { __typename } }`, &resp) + + require.Equal(t, "Todo", resp.Todo.Typename) + }) + t.Run("update the todo status", func(t *testing.T) { var resp struct { UpdateTodo struct{ Text string } diff --git a/templates/object.go b/templates/object.go index 253fbe121d..cc3042d6c7 100644 --- a/templates/object.go +++ b/templates/object.go @@ -15,6 +15,8 @@ func (ec *executionContext) _{{$object.GQLType|lcFirst}}(sel []query.Selection, out.Values[i] = jsonw.Null switch field.Name { + case "__typename": + out.Values[i] = jsonw.String({{$object.GQLType|quote}}) {{- range $field := $object.Fields }} case "{{$field.GQLName}}": {{- template "args" $field.Args }}