Skip to content

Commit

Permalink
Merge pull request #21 from sogko/sogko/master
Browse files Browse the repository at this point in the history
Updated IDFetcherFn and GlobalIDFetcherFn to allow user to return error
  • Loading branch information
chris-ramon committed Feb 24, 2016
2 parents 055c2e5 + 495cc7b commit 6ef1878
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 23 deletions.
14 changes: 9 additions & 5 deletions examples/starwars/schema.go
@@ -1,6 +1,7 @@
package starwars

import (
"errors"
"github.com/graphql-go/graphql"
"github.com/graphql-go/relay"
"golang.org/x/net/context"
Expand Down Expand Up @@ -103,15 +104,18 @@ func init() {
* way we resolve an object that implements node to its type.
*/
nodeDefinitions = relay.NewNodeDefinitions(relay.NodeDefinitionsConfig{
IDFetcher: func(id string, info graphql.ResolveInfo, ctx context.Context) interface{} {
IDFetcher: func(id string, info graphql.ResolveInfo, ctx context.Context) (interface{}, error) {
// resolve id from global id
resolvedID := relay.FromGlobalID(id)

// based on id and its type, return the object
if resolvedID.Type == "Faction" {
return GetFaction(resolvedID.ID)
} else {
return GetShip(resolvedID.ID)
switch resolvedID.Type {
case "Faction":
return GetFaction(resolvedID.ID), nil
case "Ship":
return GetShip(resolvedID.ID), nil
default:
return nil, errors.New("Unknown node type")
}
},
TypeResolve: func(value interface{}, info graphql.ResolveInfo) *graphql.Object {
Expand Down
12 changes: 7 additions & 5 deletions node.go
Expand Up @@ -18,8 +18,8 @@ type NodeDefinitionsConfig struct {
IDFetcher IDFetcherFn
TypeResolve graphql.ResolveTypeFn
}
type IDFetcherFn func(id string, info graphql.ResolveInfo, ctx context.Context) interface{}
type GlobalIDFetcherFn func(obj interface{}, info graphql.ResolveInfo, ctx context.Context) string
type IDFetcherFn func(id string, info graphql.ResolveInfo, ctx context.Context) (interface{}, error)
type GlobalIDFetcherFn func(obj interface{}, info graphql.ResolveInfo, ctx context.Context) (string, error)

/*
Given a function to map from an ID to an underlying object, and a function
Expand Down Expand Up @@ -62,8 +62,7 @@ func NewNodeDefinitions(config NodeDefinitionsConfig) *NodeDefinitions {
if iid, ok := p.Args["id"]; ok {
id = fmt.Sprintf("%v", iid)
}
fetchedID := config.IDFetcher(id, p.Info, p.Context)
return fetchedID, nil
return config.IDFetcher(id, p.Info, p.Context)
},
}
return &NodeDefinitions{
Expand Down Expand Up @@ -121,8 +120,11 @@ func GlobalIDField(typeName string, idFetcher GlobalIDFetcherFn) *graphql.Field
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
id := ""
if idFetcher != nil {
fetched := idFetcher(p.Source, p.Info, p.Context)
fetched, err := idFetcher(p.Source, p.Info, p.Context)
id = fmt.Sprintf("%v", fetched)
if err != nil {
return id, err
}
} else {
// try to get from p.Source (data)
var objMap interface{}
Expand Down
23 changes: 14 additions & 9 deletions node_global_test.go
@@ -1,6 +1,7 @@
package relay_test

import (
"errors"
"fmt"
"github.com/graphql-go/graphql"
"github.com/graphql-go/graphql/testutil"
Expand Down Expand Up @@ -30,15 +31,19 @@ var globalIDTestUserType *graphql.Object
var globalIDTestPhotoType *graphql.Object

var globalIDTestDef = relay.NewNodeDefinitions(relay.NodeDefinitionsConfig{
IDFetcher: func(globalID string, info graphql.ResolveInfo, ctx context.Context) interface{} {
IDFetcher: func(globalID string, info graphql.ResolveInfo, ctx context.Context) (interface{}, error) {
resolvedGlobalID := relay.FromGlobalID(globalID)
if resolvedGlobalID == nil {
return nil
return nil, errors.New("Unknown node id")
}
if resolvedGlobalID.Type == "User" {
return globalIDTestUserData[resolvedGlobalID.ID]
} else {
return globalIDTestPhotoData[resolvedGlobalID.ID]

switch resolvedGlobalID.Type {
case "User":
return globalIDTestUserData[resolvedGlobalID.ID], nil
case "Photo":
return globalIDTestPhotoData[resolvedGlobalID.ID], nil
default:
return nil, errors.New("Unknown node type")
}
},
TypeResolve: func(value interface{}, info graphql.ResolveInfo) *graphql.Object {
Expand Down Expand Up @@ -84,12 +89,12 @@ func init() {
},
Interfaces: []*graphql.Interface{globalIDTestDef.NodeInterface},
})
photoIDFetcher := func(obj interface{}, info graphql.ResolveInfo, ctx context.Context) string {
photoIDFetcher := func(obj interface{}, info graphql.ResolveInfo, ctx context.Context) (string, error) {
switch obj := obj.(type) {
case *photo2:
return fmt.Sprintf("%v", obj.PhotoId)
return fmt.Sprintf("%v", obj.PhotoId), nil
}
return ""
return "", errors.New("Not a photo")
}
globalIDTestPhotoType = graphql.NewObject(graphql.ObjectConfig{
Name: "Photo",
Expand Down
18 changes: 14 additions & 4 deletions node_test.go
@@ -1,8 +1,11 @@
package relay_test

import (
"errors"
"fmt"
"github.com/graphql-go/graphql"
"github.com/graphql-go/graphql/gqlerrors"
"github.com/graphql-go/graphql/language/location"
"github.com/graphql-go/graphql/testutil"
"github.com/graphql-go/relay"
"golang.org/x/net/context"
Expand Down Expand Up @@ -34,14 +37,14 @@ var nodeTestUserType *graphql.Object
var nodeTestPhotoType *graphql.Object

var nodeTestDef = relay.NewNodeDefinitions(relay.NodeDefinitionsConfig{
IDFetcher: func(id string, info graphql.ResolveInfo, ctx context.Context) interface{} {
IDFetcher: func(id string, info graphql.ResolveInfo, ctx context.Context) (interface{}, error) {
if user, ok := nodeTestUserData[id]; ok {
return user
return user, nil
}
if photo, ok := nodeTestPhotoData[id]; ok {
return photo
return photo, nil
}
return nil
return nil, errors.New("Unknown node")
},
TypeResolve: func(value interface{}, info graphql.ResolveInfo) *graphql.Object {
switch value.(type) {
Expand Down Expand Up @@ -266,11 +269,18 @@ func TestNodeInterfaceAndFields_AllowsRefetching_ReturnsNullForBadIDs(t *testing
Data: map[string]interface{}{
"node": nil,
},
Errors: []gqlerrors.FormattedError{
{
Message: "Unknown node",
Locations: []location.SourceLocation{},
},
},
}
result := graphql.Do(graphql.Params{
Schema: nodeTestSchema,
RequestString: query,
})

if !reflect.DeepEqual(result, expected) {
t.Fatalf("wrong result, graphql result diff: %v", testutil.Diff(expected, result))
}
Expand Down

0 comments on commit 6ef1878

Please sign in to comment.