@cypher fields
The generated API covers lookups, lists, filters, aggregates and keyed
writes. For anything else (a recommendation, a multi-hop traversal, a
domain-specific write) back a field with a Cypher statement of your own.
A @cypher field can sit on a node type, on Query or on Mutation.
type Festival @node {
key: ID! @key
name: String!
similar(limit: Int = 3): [Festival!]!
@cypher(
statement: """
MATCH (this)-[:IN_GENRE]->(:Genre)<-[:IN_GENRE]-(other:Festival)
WHERE other.key <> this.key
RETURN other ORDER BY other.name LIMIT $limit
"""
columnName: "other"
)
}
type Query {
festivalCount: Int!
@cypher(statement: "MATCH (f:Festival) RETURN count(f) AS n")
}
type Mutation {
renameGenre(key: String!, name: String!): Genre
@cypher(
statement: """
MATCH (g:Genre) WHERE g.key = $key
SET g.name = $name
RETURN g
"""
)
}
Query and Mutation are the only places you declare root fields
yourself, and every field on them needs @cypher.
What a statement can use
| Name | Holds |
|---|---|
this | The parent node, on a field of a node type |
$<argument> | Each field argument, by name |
$jwt | The request's claims as one map. null when signed out |
$viewer | The @key of the caller's node. See the caller |
Any other $name is a model error at startup. There is no $context:
pass what a statement needs as an argument or a claim.
Arguments must be scalars, enums or lists of them. jwt and viewer are
reserved argument names. SDL defaults (limit: Int = 3) are published in
the schema and applied at execution, and an explicit null for an
argument that has a default gets the default too. That matters for
LIMIT and SKIP, which the engine refuses with null: give those
arguments a default.