Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
08-17-2020 09:25 AM
I'm using the neo4j-graphql-js
library to interact with my Neo4j database using a GraphQL API - an issue that keeps cropping up is being forced to re-define custom cypher logic in all instances of an interface.
For example:
interface Base {
field: String!
}
type DerivedA {
field: String! @cypher(statement: """ my long cypher query """)
}
type DerivedB {
field: String! @cypher(statement: """ my long cypher query """)
}
Where the implementation of field
is exactly the same in all types derived from the interface. Is there a way I can re-use this code without copy and pasting it everywhere?
08-17-2020 09:40 AM
Welcome to the forums Jamie. I think it should be possible to include the @cyper query in the root of the interface, so that you would only have to declare it once. Have you tried that?
08-18-2020 04:59 AM
@MuddyBootsCode - trying to replicate my issue using a minimal code example I now realize that what you describe above does work for trivial examples, but breaks in my actual code base. Should have tried this earlier! Stripping my codebase down, I've create an example which still triggers what I believe is a bug in neo4j-graphql-js
:
This is my schema:
# An interaction between two sets of entities
type Interaction {
kind: String! # Type of interaction that occured, eg, visited, spoke to, etc
subjects: [Entity] @cypher(statement: """
MATCH(this:Interaction)<-[:PARTICIPATED_IN { subject: true }]-(e:Entity)
RETURN e
""")
objects: [Entity] @cypher(statement: """
MATCH(this:Interaction)<-[:PARTICIPATED_IN { subject: false }]-(e:Entity)
RETURN e
""")
participants: [Entity] @cypher(statement: """
MATCH(this:Interaction)<-[:PARTICIPATED_IN]-(e:Entity)
RETURN e
""")
# ... extra fields for time, location, etc
}
interface Entity {
name: String!
subjectIn: [Interaction] @cypher(statement: """
MATCH(this:Entity)-[:PARTICIPATED_IN { subject: true }]->(i:Interaction)
RETURN i
""")
objectIn: [Interaction] @cypher(statement: """
MATCH(this:Entity)-[:PARTICIPATED_IN { subject: false }]->(i:Interaction)
RETURN i
""")
participantIn: [Interaction] @cypher(statement: """
MATCH(this:Entity)-[:PARTICIPATED_IN]->(i:Interaction)
RETURN i
""")
}
type Person implements Entity {
name: String!
# ... other Person fields ...
}
type Place implements Entity {
name: String!
# ... other Person fields ...
}
If I seed the DB with this data:
MERGE(a:Person:Entity { name: "Bob"})
MERGE(b:Place:Entity { name: "England"})
MERGE(i:Interaction { kind: "visited"})
MERGE (a)-[:PARTICIPATED_IN { subject: true }]->(i)
MERGE (b)-[:PARTICIPATED_IN { subject: false }]->(i)
RETURN *;
The following query fails:
query {
Person {
name
subjectIn {
kind
objects {
name
}
}
}
}
With the error:
"Variable `undefined` not defined (line 1, column 44 (offset: 43))\n\"MATCH (`person`:`Person`) RETURN `person` {undefined} AS `person`\"\n
I actually wonder if this is another intance of a bug I (and others) have reported on github:
Do you think my above GraphQL schema and query should work? (in which case this is a bug in neo4j-graphql-js
, or am I missunderstanding something about how this should work?
08-18-2020 05:27 AM
It's possible, though one things that jumps out is that normally when specifying your cyper query you would omit the type, so something like:
MATCH (this)
vs.
MATCH (this:Entity)
It may be worth a try otherwise I would think that it's a bug somewhere in the code for sure. Also, I know this was in your first post but it may just require doing copy pasta of the field definition for the implementation types.
08-18-2020 05:41 AM
Removing the type from the Cypher query didn't make any difference.
Copy and pasting the query to all derived types fixes the error, its just a pain to keep them all in sync when there are many more than just 2 shown here.
Thanks for the help.
08-18-2020 05:45 AM
I totally understand, there are some aspects of this that are just pain and the library hasn't smoothed it out much.
All the sessions of the conference are now available online