RFC: Mutable and null able @id field in GraphQL

Motivation

@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.

Implementation

Here, I will go over a couple of things we need to change to have editable and nullable @id fields.

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 @id field 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 @id fields which are unique across all the implementing types of the interface. The process will be similar as adding a node.
    Inherited unique @id fields 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 @id field not possible because we can’t have same value of @id field for multiple nodes. We can give error if filter results in multiple nodes, and it will be best practice for users to give @id field in filter itself, whenever possible.
    But it can also happen that none of the @id fields is present for the node as we are now making @id fields 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 @id field.
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.

References:
RFC: Allow multiple unique fields in graphql schema
Editable @id fields
Nullable @id field

Please also support when no @id fields are required if the ID is in the schema:

type Foo {
  id: ID
  bar: Int @id # not required
  baz: String @id # also not required
}
2 Likes

yeah, that will be possible. Now we are not enforcing any primary @id field but it will be upto user how he wants to filter the node that needs to be updated. ID field is always an option.

And also with upserts we will give error if there are multiple @id fields and there exist multiple nodes satisfying those fields.

Any timeline on implementing this?

Thanks.

Hi @eugaia , Welcome to Dgraph Community!!
We are currently working on this feature and it will be added in master branch by the end of next week.
And then it will be part of 21.07 release.

@JatinDevDG - Thank you for your quick response (and welcome). :slight_smile:

What’s the timeline for rollout of 21.07?

Thanks.

21.07 will be released in July 2021.

1 Like

Perfect, thanks again for the quick response.

Keep up the awesome work!

1 Like

Could this feature please be cherry-picked into 21.03.1 ?

Sorry @maaft, patch releases are only meant for bug fixes, not major features. You have to wait for 21.07.

Support for mutable and nullable @id fields has been merged to master branch and will be avaliable in 21.07 release.
PR:Feat(GRAPHQL): This PR allows updatable and nullable @id fields. by JatinDevDG · Pull Request #7736 · dgraph-io/dgraph · GitHub

alright, wasn’t aware that is is something major.

I was asking because changes/features have been cherry picked in the past into patch releases.

yeah in the past this has created problems, so we now do a lot of testing before releasing a feature and that happens in a major release. There are couple of bugs that we need to fix regarding the above feature.

2 Likes