@id fields in GraphQL are currently not editable. Once entered we can’t change the value of these fields. Also, these fields are currently non-nullable.
Also we can now have multiple @id fields in a type, having all of them non-nullable is not a good design.
These improvements on
@id fields are pending for some time now and asked by many users and have use cases around them. Also, we now have a much simpler mutation rewriting code that will allow us to do change this behavior much quickly.
Here, I will go over a couple of things we need to change to have editable and nullable
Changes in update mutation
Currently @id fields are not added to update mutation patch, firstly we need to add them to update mutation patch.
While doing update mutation, we need to make an existence query (same as we do in addition case) to check if there exists a node for a given value of the
@idfield or not. Based on that result we need to give an error or update the field.
Also, we need to take care of inherited unique
@idfields which are unique across all the implementing types of the interface. The process will be similar as adding a node.
@idfields are being added and change is currently in review
Feat(GraphQL): This PR allows @id field in interface to be unique across all the implementing types. by JatinDevDG · Pull Request #7710 · dgraph-io/dgraph · GitHub
While doing update mutation, we need to give filter to select nodes to update.If filter results in multiple nodes, then updation of
@idfield not possible because we can’t have same value of
@idfield for multiple nodes. We can give error if filter results in multiple nodes, and it will be best practice for users to give
@idfield in filter itself, whenever possible.
But it can also happen that none of the
@idfields is present for the node as we are now making
@idfields non-nullable. Then in some cases, there is no way to filter that particular node.
The solution to this is to enforce at least one @id field non-nullable, something like primary key.
Changes in Add mutation with upsert
This case is much complex. Currently, while doing Add mutation with upsert we use given
@id fields in mutation to search existing nodes. if any of the
@id fields exist in some node we return that node and otherwise, we add the node with all of the given fields.
And if there are multiple
@id fields and there are multiple nodes corresponding to them then we select a node randomly and update all fields apart from
Note: This behaviour also needs to be fixed , we need to give flexibility to users to select an
@id field which will be used to search the nodes while doing upserts when multiple nodes are present.
Now , If we make
@id field mutable then there is no way to search the existing node because we use @id fields to search a node in upserts and that itself can be updated. For this, we can change the design to have a
primary @id field that user can specify in the schema that will be used to do upserts(in that case primary @id field is not update able), or user needs to define which
@id field they want us to use for upserts.
And also as we are making @id fields nullable then it is also possible that in add mutation no @id is present then also we don’t have a way to do upserts. That can again be solved by having primary @id field that is not nullable.
As of now, we are thinking of not changing the upsert behaviour and if user need to update the
@id field then they can use update mutation.