Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
11-29-2018 07:56 AM
I have developed an interface which several node types are implemented with using the same syntax found here. I can not however figure out how to query that defined interface, or if that is even possible.
Using the example found in the linked document above. How would I query the "Person" interface?
When I try and query my interface I get an empty list inside of my object.
Thanks
11-29-2018 01:29 PM
Could you share the query you have so far?
If you have an Actor type that implements the Person interface, then you'll want to use an Inline Fragment in the query. For example, from that sample schema getting actors for a movie would look something like:
{
Movie {
actors {
... on Actor {
name
}
}
}
}
11-29-2018 02:15 PM
I was trying something like below.
{
Person{
name
born
}
}
I was thinking that the interface was the parent of the node type that implements it. So you have to access the specific node type before referring to the interface? Is it possible to just query all the node types of a specific interface, like the example above?
Could you also explain the difference between "Implements" & "Extends"? I tried to use "extends" in-place of "implements" but Neo4j reject the idl.
12-03-2018 01:49 PM
Is there a way to query all nodes and relationships using graphQL?
02-11-2019 06:40 PM
Having similar issues with using interfaces.
If I query an interface, I receive the following error when trying to query one of the types on that interface
"message": "Abstract type Entity must resolve to an Object type at runtime for field Query.entities with value { uuid: \"6b270c306e6a11e8bfe8b8e85647febc\" }, received \"undefined\". Either the Entity type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function.",
When I query a type that has a relationship to an in interface, I receive the following error:
"Resolve function for \"Organization.commonName\" returned undefined",
I've tried following all the GraphQL/Apollo documentation, like adding __resolveType and __typeOf resolvers and exposing the schema & fragment types to the client cache.
Apollo guidance - Unions & interfaces
Apollo guidance - Fragment matcher
I feel like I'm losing my mind because I can't figure this one out...any ideas?
04-02-2019 02:17 AM
I'm getting the same error as @btroop. Has anyone figured out how to use inline fragments on interface types with neo4j-graphql-js?
04-04-2019 10:13 AM
Hey @smkhalsa can you share your typedefs and the query? We use a couple of interface types in the tests for neo4j-graphql-js, for example here in the typedefs
andan example query that we run in the tests looks like this:
{
Movie(title: "River Runs Through It, A") {
title
ratings {
rating
User {
... on User {
name
userId
}
}
}
}
}
Could be we aren't properly handling more complex uses of inline fragments?
04-04-2019 01:50 PM
Hey @William_Lyon, I created a gist with a minimal reproduction of the issue:
For the interface query, it seems to fail regardless of whether or not inline fragments are used. For some reason, the value of the __resolveType resolver is not getting passed back in the response.
For example, the query:
query {
PlaylistInterface {
id
name
}
}
results in the following error:
Abstract type Playlist must resolve to an Object type at runtime for field Query.PlaylistInterface with value { name: \"My Favorite Songs\", id: \"0ae75bb2-d7cd-4914-81ea-2d57594cbdfb\" }, received \"undefined\". Either the Playlist type should provide a \"resolveType\" function or each possible type should provide an \"isTypeOf\" function.
Also, the following union query...
query {
PlaylistUnion {
... on PublicPlaylist {
id
}
... on UserPlaylist {
id
}
}
}
... fails with this error:
schemaType.getFields is not a function
04-11-2019 03:33 AM
@William_Lyon have you had a chance to look at this? Interfaces and Unions are currently blockers for me. Let me know if there is anything I can do to help.
05-01-2019 08:57 PM
Hey @smkhalsa - sorry for the delay. Thanks for the example, I was able to reproduce your error.
Unfortunately, we don't yet have support for union types, so I'm not surprised by the union error
But regarding the PlaylistInterface query - our initial interface implementation adds a FRAGMENT_TYPE
field to the generated Cypher query by inspecting the implemented type from the GraphQL resolveinfo object, with the idea that this FRAGMENT_TYPE
field is then picked up in the __resolveType
resolver. To make this work, augmentSchema
adds a __resolveType
resolver for any interfaces that is essentially this:
const resolvers = {
SomeInterface: {
__resolveType(obj, context, info){
return obj["FRAGMENT_TYPE"];
},
},
};
however, it looks like we don't check for already existing __resolveType
resolvers, so this ends up overwriting the __resolveType
resolvers you've implemented. This we can fix easily, in fact a workaround would be to use makeExecutableSchema
and implement a Query field resolver that just delegates to neo4jgraphql
:
import { makeExecutableSchema } from "apollo-server";
import { neo4jgraphql } from "neo4j-graphql-js";
...
const resolvers = {
Query: {
PlaylistInterface: neo4jgraphql
},
Playlist: {
__resolveType: (collection) => {
return collection.imageName ? "PublicPlaylist" : "UserPlaylist"
}
}
};
const schema = makeExecutableSchema({
resolvers,
typeDefs
});
const server = new ApolloServer({
schema,
resolvers,
context: { driver }
});
I tested this out and this does result in the provided __resolveType
resolver getting called, but we don't actually grab the imageName
field from the database since it isn't a field on Playlist
. I suppose we could add some logic to add all fields for the implemented type so they would be available in the __resolveType
resolver.
It seems something happened with our FRAGMENT_TYPE
approach as that doesn't appear to be working properly, and unfortunately we didn't have good tests around this so not sure what went wrong there. This will require some investigation.
I'll push a fix to check for implemented __resolveType
resolvers before adding them in the augment schema step for now. That's at least a start.
Thanks for bearing with us as we fix this up, I recognize the importance of getting interface and unions working properly.
10-07-2019 02:25 PM
I know I'm coming in to this late, but I j
ust wanted to thank you for this explanation as it cleared a lot of things up for me. Also, I think adding logic to inject all fields into the __resolveType function is a great idea. Otherwise implementing discriminated Union types (via interfaces or unions) becomes impossible unless the user includes the discriminator field in the GQL query.
Basically, +1 for this feature.
03-04-2020 06:59 AM
Hi there, I'm just wondering if there has been any progress on supporting union types? Thanks!
05-05-2019 04:36 AM
Thanks @William_Lyon for the response. I look forward to the custom __resolveType fix.
This might be a bit complicated since we wouldn't know how deep to go. For example, what if my __resolveType resolver depends on a relation or a related node. This would be the case for UserPlaylist (i.e. does a CREATED_BY relation exist?). One solution could be to provide an optional "resolveTypeFragments" map to augmentSchema or makeAugmentedSchema that would allow users to pass in a Fragment to include for a given interface. Alternative, we could just require that any dependent fields be explicitly defined in the query for custom __resolveType implementations.
Any estimate for when we might get union types working?
01-08-2021 07:51 AM
I'm facing the same issue also. Any update for this issue?
01-09-2021 07:00 AM
I found a workaround (hacky as hell....)
After running schema = makeAugmentedSchema (...) you can add the resolveType to the object.
schema._typeMap.SomeInterface.resolveType = (collection) => {
return collection.imageName ? "PublicPlaylist" : "UserPlaylist"
};
All the sessions of the conference are now available online