Database mapping
This page describes how to use directives for database mapping.
@alias
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 {
id: ID! @id @alias(property: "dbId")
username: String!
}
type User {
id: ID! @id
username: String! @alias(property: "dbUserName")
livesIn: [City!]! @relationship(direction: OUT, type: "LIVES_IN", properties: "UserLivesInProperties")
}
type City {
name: String
}
interface UserLivesInProperties @relationshipProperties {
since: DateTime @alias(property: "moveInDate")
}
Note that the property in aliases are automatically escaped (wrapped with backticks ``), so there is no need to add escape characters around them.
@plural
This directive redefines how to compose the plural of the type for the generated operations. This is particularly useful for types that are not correctly pluralized or are non-English words. Take this type definition as an example:
type Tech @plural(value: "Techs") {
name: String
}
This way, instead of the wrongly generated teches
, the type is properly written as techs
:
{
techs {
title
}
}
The same is applied to other operations such as createTechs
.
However, keep in mind that database labels are not changed with this directive.
@node
This directive is used to specify the configuration of a GraphQL object type which represents a Neo4j node. It can be appended with the following optional parameters:
labels
This parameter defines the list of label to be used in Neo4j instead of the GraphQL type name:
type Dog @node(labels: ["K9"]) {
name: String!
}
This way, the following query:
{
dogs {
name
}
}
Generates the Cypher query:
MATCH (this: K9)
RETURN this { .name } as name
If the GraphQL type name should still be used as a label, it needs to be specified as well:
type Dog @node(labels: ["Dog", "K9"]) {
name: String!
}
This way, the following query:
{
dogs {
name
}
}
Generates the Cypher query:
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
}
Using $jwt
and $context
In some cases, you may want to generate dynamic labels depending on the user requesting.
For that, you can use the variable $jwt
to define a custom label in the JWT:
type User @node(labels: ["$jwt.username"]) {
name: String!
}
The following query yielda 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:
MATCH (this:arthur)
RETURN this { .name } as this
Similarly, context values can be passed directly:
type User @node(label: ["$context.appId"]) {
name: String!
}
When running the server with Apollo:
const server = new ApolloServer({
schema: await neoSchema.getSchema(),
});
await startStandaloneServer(server, {
context: async ({ req }) => ({ req, appId: "myApp" }),
});