Database mapping
This is the documentation of the GraphQL Library version 6. For the long-term support (LTS) version 5, refer to GraphQL Library version 5 LTS. |
This page describes how to use directives for database mapping. Each type in your GraphQL type definitions can be mapped to an entity in your Neo4j database, such as nodes, relationships, and relationship properties.
@node
Definition
"""Informs @neo4j/graphql of node metadata"""
directive @node(
"""The labels to map this GraphQL type to in the Neo4j database"""
labels: [String!]
) on OBJECT
Usage
Adding the @node
directive to your GraphQL type specifies that it represents a Neo4j node.
For example, to represent a Neo4j node with the label "Movie" and a single property "title" of type string:
type Movie @node {
title: String
}
In version 6.x, it’s not required to specify every GraphQL type representing a Neo4j node with the |
When not differently specified, the GraphQL type name is used as a label for the represented Neo4j node. It’s possible to explicitly define the Neo4j node labels by using the parameter labels
.
The labels
parameter
You can append the optional parameters labels
to a GraphQL object with the @node
directive.
This parameter lists the labels to be used in Neo4j instead of the GraphQL type name.
labels
parameterConsider the following type definition:
type Dog @node(labels: ["K9"]) {
name: String!
}
Here is a query against the Dog
node:
{
dogs {
name
}
}
The following Cypher is generated:
MATCH (this: K9)
RETURN this { .name } as name
If you want to use the GraphQL type name as a label, specifiy both.
labels
parameterConsider the following type definition:
type Dog @node(labels: ["Dog", "K9"]) {
name: String!
}
Here is an example for a query against the Dog
node
{
dogs {
name
}
}
The following Cypher is generated:
MATCH (this:Dog:K9)
RETURN this { .name } as this
Defining |
The following example results in a unique constraint to be asserted for the label K9
and the property name
:
type Dog @node(labels: ["K9", "Dog"]) {
name: String! @unique
}
See @unique
to learn more about the @unique
directive.
Using $jwt
and $context
In some cases, you may want to generate dynamic labels depending on the user requesting.
You can use the variable $jwt
to define a custom label in the JWT.
$jwt
variable in the labels
parameterConsider the following type definition:
type User @node(labels: ["$jwt.username"]) {
name: String!
}
The following query yields a different Cypher query depending on the user JWT:
{
users {
name
}
}
Assuming there is a user with the value "username": "arthur"
in JWT, the Cypher query looks like this:
MATCH (this:arthur)
RETURN this { .name } as this
Similarly, context values can be passed directly:
type User @node(label: ["$context.appId"]) {
name: String!
}
For example, if you are running the server with Apollo:
const server = new ApolloServer({
schema: await neoSchema.getSchema(),
});
await startStandaloneServer(server, {
context: async ({ req }) => ({ req, appId: "myApp" }),
});
@relationship
Definition
"""
Instructs @neo4j/graphql to treat this field as a relationship. Opens up the ability to create and connect on this field.
"""
directive @relationship(
type: String!
"""Valid and default directions for this relationship."""
queryDirection: RelationshipQueryDirection = DEFAULT_DIRECTED
direction: RelationshipDirection!
"""
The name of the interface containing the properties for this relationship.
"""
properties: String
"""
Prevent all but these operations from being generated for this relationship
"""
nestedOperations: [RelationshipNestedOperations!]! = [CREATE, UPDATE, DELETE, CONNECT, DISCONNECT, CONNECT_OR_CREATE]
"""Prevent aggregation for this relationship"""
aggregate: Boolean = true
) on FIELD_DEFINITION
Usage
Relationships are represented by marking particular fields with a directive — in this case, @relationship
.
It defines the relationship type in the database, as well as which direction that relationship goes in.
To add two node types, "Movie" and "Actor", and connect the two:
type Movie {
title: String
actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN)
}
type Actor {
name: String
movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}
The |
See also: @relationship
field configuration.
@relationshipProperties
Definition
"""Required to differentiate between interfaces for relationship properties, and otherwise."""
directive @relationshipProperties on OBJECT
@relationshipProperties
can only be used on interfaces.
Usage
In order to add properties to a relationship, add a new type to your type definitions decorated with the @relationshipProperties
directive.
For example, for the "ACTED_IN" relationship, add a property "roles":
type Movie {
title: String
actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn")
}
type Actor {
name: String
movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, properties: "ActedIn")
}
type ActedIn @relationshipProperties {
roles: [String]
}
Note that in addition to this type, there is an added key properties
in the existing @relationship
directives.
For more information, see Type definitions → Relationships.
@alias
Definition
"""
Instructs @neo4j/graphql to map a GraphQL field to a Neo4j node or relationship property.
"""
directive @alias(
"""The name of the Neo4j property"""
property: String!
) on FIELD_DEFINITION
Usage
This directive maps a GraphQL field to a Neo4j property on a node or relationship.
It can be used on any fields that are not @cypher
or @relationship
fields.
For example:
type User @node {
id: ID! @id @alias(property: "dbId")
username: String!
}
type User @node {
id: ID! @id
username: String! @alias(property: "dbUserName")
livesIn: [City!]! @relationship(direction: OUT, type: "LIVES_IN", properties: "UserLivesInProperties")
}
type City @node {
name: String
}
type UserLivesInProperties @relationshipProperties {
since: DateTime @alias(property: "moveInDate")
}
The property in aliases are automatically escaped (wrapped with backticks ``), so there is no need to add escape characters around them. |