merging type systems failed: unable to build object definition: unable to find type path/to/proto.SearchResponse
go list that/path
work inside the project dir?
@ethanrubio
You get it from the ID. According to the spec, the id is a global identifier, and using the id would guarantee that the same object always gets returned. So matching it on __typename
would probably be breaking the relay spec.
I solved it like this:
func (r *queryResolver) Node(ctx context.Context, globalId string) (Node, error) {
loaders := tenants.LoadersFromContext(ctx)
nodeType, id, err := fromGlobalId(globalId)
if err != nil {
return nil, err
}
switch nodeType {
case "User":
return loaders.User().Load(id)
case "Organization":
return loaders.Organization().Load(id)
case "Group":
return loaders.Group().Load(id)
default:
return nil, fmt.Errorf("type not supported: %s", nodeType)
}
}
var globalIdSeparator = ":"
func toGlobalId(typeName string, id primitive.ObjectID) string {
return base64.StdEncoding.EncodeToString([]byte(typeName + globalIdSeparator + id.Hex()))
}
func fromGlobalId(globalId string) (typeName string, id primitive.ObjectID, err error) {
decoded, err := base64.StdEncoding.DecodeString(globalId)
if err != nil {
return "", primitive.NilObjectID, nil
}
ids := strings.Split(string(decoded), globalIdSeparator)
if len(ids) != 2 {
return "", primitive.NilObjectID, fmt.Errorf("invalid global id format")
}
typeName = ids[0]
id, err = primitive.ObjectIDFromHex(ids[1])
return
}
Of course, that requires a resolver for each ID in all models.
It would probably be nice if it was possible to create a generic ID resolver/marshaller that gets the entire model and not just the field value (to be able to get the model type), not sure if that's possible.
@vektah, it does say so in that document:
"This id should be a globally unique identifier for this object, and given just this id, the server should be able to refetch the object."
"If a query returns an object that implements Node, then this root field should refetch the identical object when value returned by the server in the Node‘s id field is passed as the id parameter to the node root field."
It doesn't explicitly say that it needs to identify the type, but it needs to be globally unique, so where would be a better way to put it, and also guarantee global uniqueness, especially if using a regular db and primary keys :)
And, if I recall correctly, that is how the relay package for js does ;)
Hi I'm looking to use the feature introduced in 99designs/gqlgen#375. I am forced to use a single version of mapstucture
(the latest) and it has caused errors in slices_test.go
. gqlgen
is on an older version, upgrading mapstructure
in gqlgen
will break the tests. The code asserts Test1 []string
and Test3 []*string
should resolve to nil
and []
respectively. The newer version of mapstructure will return nil
for all or []
for all depending on the value of ZeroFields
.
Does this test have anything to do with the feature (always use pointers in resolver return types)? Do you know what errors having the different versions might cause?