Moved from GitHub dgraph/5697
Posted by CosmicPangolin:
What version of Dgraph are you using?
v20.03.3
Have you tried reproducing the issue with the latest release?
No, but I didn’t see a fix in a quick scan of the changelog
What is the hardware spec (RAM, OS)?
GCloud VM 8gb
Steps to reproduce the issue (command/config used to run Dgraph).
Consider a schema with something like the following (this is probably more complicated than necessary, but it matches my case):
interface Post{
thread: Thread! @hasInverse(field: posts)
id: ID!
type: String! // Serialized type
updatedTime: Int!
createdTime: Int! @search
replies: [Post!] @hasInverse(field: parentPost)
parentPost: Post @hasInverse(field: replies)
user: User!
}
Expected behaviour and actual result.
When Post is an interface, the PostRef generated only includes the id field. If we’re serializing data to produce mutation inputs, a PostRef input for parentPost requires serializing the relevant Post object with only an id, or an ‘undefined location’ error is thrown. I think concrete TypeRefs expose all first-order fields, which allows us a lot more convenience designing generic mutation methods for our data…we can serialize objects with some simple nested data to define edges, which feels pretty good (though I think the endpoint still rejects nested data w/ non-null predicates…see comment at the end).
But allowing fields in the TypeRef also specifically unlocks our ability to append the ‘type’ field as a discriminator during serialization, before our data hits the wire - the endpoint doesn’t reject our ‘type’ field in any other cases that I’m aware of.
A discriminator field is a common feature in serialization libraries, and core to our data systems design…so I hope it’s possible to squeeze this into 2020.07. We’ve realized it takes some serialization/modeling gymnastics to strip out discriminators from predicate objects in this case. Our easiest workaround is to manually identify mutations with interface fields, null the associated predicate objects before serialization, construct strings to represent them, stringify the serialized data, and splice the predicate representations back in
This is a similar issue to the TypePatch object lacking the ‘id’ field - in that it’s largely a problem when building generified methods for handling data - but is much more difficult to work around because the discriminator field can’t easily be nulled, and is even required in most other queries/mutations since it’s used for deserialization.
I think ideally nested predicate fields should not get rejected either, and the endpoint would simply look at the ids of first order relations to draw edges…then we could pass any data object as-is for storage. The endpoint selectively rejecting fields defined in schema makes programmatically saving data unintuitive and difficult in general.