I’m currently learning dgraph to implement a quite particular use case.
long story short I have a system in place which feeds a large quantity of data in dgraph and I’m aiming to serve the data through GraphQL.
Being GraphQL the only way to query data, I designed the GraphgQL schema first and i built a component that generates the correct RDF to match the GraphQL schema.
Tha major issue I faced using RDF mutation to insert data is the hasInverse directive.
Using this particular directive dgraph generates 2 separate predicate which are kept synced using GraphQL:
type Text {
text: String @search(by: [hash])
is_name: [Person!] @hasInverse(field: name)
}
type Person {
name: Text!
}
Generates
which is properly handled as long as the data is inserted though GraphQL, for instance, a mutation like
mutation {
addPerson(input: [{name: {text: "paolo"}}]) {
person {
name {
text
}
}
}
}
creates both the relation Person.name and Text.is_name
However using RDFs it’s required to build the rdf to manually set both relation in order to keep the schema consistent
{
set {
_:paolo <dgraph.type> "Person" .
_:name <dgraph.type> "Text" .
_:name <Text.text> "Paolo" .
_:paolo <Person.name> _:name .
_:name <Text.is_name> _:paolo .
}
}
This becomes quite tricky if the schema grows or if updates / deletions are performed.
Exploiting the dgraph directive i figured out how to build a proper inverse relation in order to keep the “link” consistent in GraphQL without the need of update 2 relations:
Having a predicate in dgraph such as
Person.name uid
reverse
is possible to insert a GraphQL schema like
type Text {
text: String @search(by: [hash])
is_name: [Person!] @dgraph(pred: "~Person.name")
}
type Person {
name: Text @dgraph(pred: "Person.name")
}
Updating / inserting / deleting the relation from RDF or GrapQL it stays consistent from the perspective of both dgraph and GraphQL
After 30 lines of context, i would like to ask three things:
Is this a proper to use dgraph?
Will the GraphQL implementation change in the near future so that this solution will break?
Why isn’t this the default behaviour of a GraphQL field with hasInverse directive instead of generating 2 different predicates which do not share any information and can lead to predicates pointing to empty / null nodes?