Ask a Question


Dgraph provides two types of built-in identifiers: the ID scalar type and the @id directive.

  • The ID scalar type is used when you don’t need to set an identifier outside of Dgraph.
  • The @id directive is used for external identifiers, such as email addresses.

The @id directive

For some types, you’ll need a unique identifier set from outside Dgraph. A common example is a username.

The @id directive tells Dgraph to keep that field’s values unique and use them as identifiers.

For example, you might set the following type in a schema:

type User {
    username: String! @id

Dgraph requires a unique username when creating a new user. It generates the input type for addUser with username: String!, so you can’t make an add mutation without setting a username; and when processing the mutation, Dgraph will ensure that the username isn’t already set for another node of the User type.

In a single-page app, you could render the page for http://.../user/Erik when a user clicks to view the author bio page for that user. Your app can then use a getUser(username: "Erik") { ... } GraphQL query to fetch the data and generate the page.

Identities created with @id are reusable. If you delete an existing user, you can reuse the username.

Fields with the @id directive must have the type String!.

As with ID types, Dgraph generates queries and mutations so you can query, update, and delete data in nodes, using the fields with the @id directive as references.

It’s possible to use the @id directive on more than one field in a type. For example, you can define a type like the following:

type Book {
    name: String! @id
    isbn: String! @id
    genre: String!

You can then use multiple @id fields in arguments to get queries, and while searching, these fields will be combined with the AND operator, resulting in a Boolean AND operation. For example, for the above schema, you can send a getBook query like the following:

query {
  getBook(name: "The Metamorphosis", isbn: "9871165072") {

This will yield a positive response if both the name and isbn match any data in the database.

Combining ID and @id

You can use both the ID type and the @id directive on another field definition to have both a unique identifier and a generated identifier.

For example, you might define the following type in a schema:

type User {
    id: ID!
    username: String! @id

With this schema, Dgraph requires a unique username when creating a new user. This schema provides the benefits of both of the previous examples above. Your app can then use the getUser(...) { ... } query to provide either the Dgraph-generated id or the externally-generated username.

Note If in a type there are multiple @id fields, then in a get query these arguments will be optional. If in a type there’s only one field defined with either @id or ID, then that will be a required field in the get query’s arguments.