Autogeneration

@id

This directive marks a field as the unique identifier for an object type, and by default; enables autogeneration of IDs for the field and implies that a unique node property constraint should exist for the property.

The format of each generated ID is a UUID generated by randomUUID() function.

If autogeneration for an ID field is enabled, the field will not be present in input types for Mutations.

See Unique node property constraints for details on how to assert the existence of the necessary database constraints for relevant fields.

Definition

"""Indicates that the field is an identifier for the object type. By default; autogenerated, and has a unique node property constraint in the database."""
directive @id(
    autogenerate: Boolean! = true
    unique: Boolean! = true
) on FIELD_DEFINITION

Usage

The following two type definitions are equivalent in that they both specify an ID which will benefit from autogeneration:

type User {
    id: ID! @id
    username: String!
}
type User {
    id: ID! @id(autogenerate: true)
    username: String!
}

The following type definition is currently a no-op, as the @id directive only provides autogeneration as it stands:

type User {
    id: ID! @id(autogenerate: false)
    username: String!
}

You can disable the mapping of the @id directive to a unique node property constraint by setting the unique argument to false:

type User {
    id: ID! @id(unique: false)
    username: String!
}

@timestamp

Timestamps

This directive marks a field as a timestamp field, which will be used to store timestamps of when particular events happen through the GraphQL API.

These events are triggered and stored at the GraphQL API layer. Events happening in your database through other routes will not trigger updates of these timestamps.

Definition

enum TimestampOperation {
    CREATE
    UPDATE
}

"""Instructs @neo4j/graphql to generate timestamps on particular events, which will be available as the value of the specified field."""
directive @timestamp(
    """Which events to generate timestamps on. Defaults to both create and update."""
    operations: [TimestampOperation!]! = [CREATE, UPDATE]
) on FIELD_DEFINITION

Usage

The following type definition has two individual fields to store the timestamps of create and update events.

type User {
    createdAt: DateTime! @timestamp(operations: [CREATE])
    updatedAt: DateTime! @timestamp(operations: [UPDATE])
}

The following two equivalent type definitions have a single field storing the event timestamp of the last create or update:

type User {
    lastModified: DateTime! @timestamp
}
type User {
    lastModified: DateTime! @timestamp(operations: [CREATE, UPDATE])
}

@callback

The @callback directive is used to specify a function that will be invoked when updating or creating the properties on a node or relationship.

For non-required values, callbacks may return undefined (meaning that nothing will be changed or added to the property) or null (meaning that the property will be removed).

Definition

enum CallbackOperation {
    CREATE
    UPDATE
}

"""Instructs @neo4j/graphql to invoke the specified callback function when updating or creating the properties on a node or relationship."""
directive @callback(
    """Which events to invoke the callback on."""
    operations: [CallbackOperation!]! = [CREATE, UPDATE]
    """The name of the callback function."""
    name: String!
) on FIELD_DEFINITION

Usage

Type Definitions:

type Product {
    name: String!
    slug: String! @callback(operations: [CREATE, UPDATE], name: "slug")
}

Schema Construction:

Note that the callback is asynchronous!

const slugCallback = async (root) => {
    return `${root.name}_slug`
}

new Neo4jGraphQL({
    typeDefs,
    driver,
    config: {
        callbacks: {
            slug: slugCallback
        }
    }
})

Using GraphQL context values

The GraphQL context for the request is available as the third argument in a callback. This maps to the argument pattern for GraphQL resolvers.

For example, if you wanted a field modifiedBy:

type Record {
    content: String!
    modifiedBy: @callback(operations: [CREATE, UPDATE], name: "modifiedBy")
}

If the username is located in context.username, you could define a callback such as:

const modifiedByCallback = async (_parent, _args, context) => {
    return context.username;
}

new Neo4jGraphQL({
    typeDefs,
    driver,
    config: {
        callbacks: {
            modifiedBy: modifiedByCallback
        }
    }
})
The second positional argument, in this case _args, has a type of Record<string, never>, and as such will always be an empty object.