Field configuration
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. |
If you need to remove fields from a GraphQL Object Type or a GraphQL Input Object Type, consider the following type definitions:
type Movie @node {
title: String!
description: String
}
type Actor @node {
name: String!
age: Int
actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}
It generates the type Actor
:
type Actor {
name: String!
age: Int
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, directed: Boolean = true): [Movie!]!
actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}
By using the directives @selectable
, @settable
, @filterable
, and @relationship
it is possible to control how these fields are exposed.
For instance, to hide the field age
in the Selection Set, you can use the @selectable
directive:
type Movie @node {
title: String!
description: String
}
type Actor @node {
name: String!
age: Int @selectable(onRead: false, onAggregate: false)
actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}
Now the type Actor
looks like this:
type Actor {
name: String!
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, directed: Boolean = true): [Movie!]!
actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}
@relationship
There are several nested operations available for every field created using the @relationship
directive. These are create
, connect
, disconnect
, connectOrCreate
, and delete
.
However, these operations are not always needed.
The @relationship
directive allows you to define which operations should be available for a relationship by using the argument nestedOperations
.
Additionally, the @relationship
directive causes fields to be added for nested aggregations.
These can be disabled using the aggregate
argument.
Definition
enum NestedOperations {
CREATE
UPDATE
DELETE
CONNECT
DISCONNECT
CONNECT_OR_CREATE
}
directive @relationship(
type: String!
queryDirection: RelationshipQueryDirection! = DEFAULT_DIRECTED
direction: RelationshipDirection!
properties: String
nestedOperations: [NestedOperations!]! = [CREATE, UPDATE, DELETE, CONNECT, DISCONNECT, CONNECT_OR_CREATE]
aggregate: Boolean! = true
) on FIELD_DEFINITION
Usage
Configure aggregation
From the previous type definitions, the type Actor
produced is:
type Actor {
name: String!
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, directed: Boolean = true): [Movie!]!
actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}
Note that the relationship field actedIn
produces the operation field actedInAggregate
, which allows aggregations on that relationship.
It is possible to configure this behavior by passing the argument aggregate on the @relationship
directive:
type Movie @node {
title: String!
description: String
}
type Actor @node {
name: String!
age: Int
actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, aggregate: false)
}
In this case, as the argument aggregate
was passed as false, the type Actor
produced is:
type Actor {
name: String!
age: Int
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, directed: Boolean = true): [Movie!]!
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}
Configure nested operations
A large part of the schema produced by the library is needed to support nested operations.
These are enabled by the directive @relationship
as described in @relationship
→ Inserting data.
The nested operations available are:
enum NestedOperations {
CREATE
UPDATE
DELETE
CONNECT
DISCONNECT
CONNECT_OR_CREATE
}
By default, @relationship
enables all of them when defined.
To enable only some of them, you have to pass the argument nestedOperations
specifying the operations required.
Disable nested create
To disable the nested CREATE
operation, change the initial type definitions to:
type Movie @node {
title: String!
description: String
}
type Actor @node {
name: String!
age: Int
actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, nestedOperations: [UPDATE, DELETE, CONNECT, DISCONNECT, CONNECT_OR_CREATE])
}
As the CREATE
operation is not present in the nestedOperations
argument array, it is no longer possible to create movies starting from the Actor
type.
Disable all nested operations
If instead, no nested operations are required, it is possible to disable all the nested operations by passing an empty array:
type Movie @node {
title: String!
description: String
}
type Actor @node {
name: String!
age: Int
actedIn: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT, nestedOperations: [])
}
@selectable
This directive sets the availability of fields on queries and aggregations. It has two arguments:
-
onRead: if disabled, this field is not available on queries and subscriptions.
-
onAggregate: if disabled, aggregations is not available for this field.
Definition
"""Instructs @neo4j/graphql to generate this field for selectable fields."""
directive @selectable(onRead: Boolean! = true, onAggregate: Boolean! = true) on FIELD_DEFINITION
Usage
With the following definition:
type Movie @node {
title: String!
description: String @selectable(onRead: false, onAggregate: true)
}
The type Movie
in the resulting schema looks like this:
type Movie {
title: String!
}
This means that descriptions cannot be queried, either on top or on nested levels. Aggregations, however, are available on both:
type MovieAggregateSelection {
count: Int!
description: StringAggregateSelectionNullable!
title: StringAggregateSelectionNonNullable!
}
In case you want to remove the description
field from MovieAggregateSelection
, you need to change the onAggregate
value to false
:
type Movie @node {
title: String!
description: String @selectable(onRead: false, onAggregate: false)
}
@selectable
with relationships
This directive can be used along with relationship fields.
From the previous type definitions, the type Actor
produced is:
type Actor {
name: String!
actedIn(where: MovieWhere, sort: [MovieSort!]!, limit: Int, offset: Int, directed: Boolean = true): [Movie!]!
actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}
This means that the actedIn
field can be queried from the homonymous generated field actedIn
and the field actedInConnection
.
To avoid that, it is required to use the directive @selectable
.
For instance, these type definitions:
type Movie @node {
title: String!
description: String
}
type Actor @node {
name: String!
actedIn: [Movie!]!
@relationship(type: "ACTED_IN", direction: OUT)
@selectable(onRead: false, onAggregate: false)
}
Generate the type Actor
:
type Actor {
name: String!
actedInAggregate(where: MovieWhere, directed: Boolean = true): ActorMovieActedInAggregationSelection
}
Note how actedInAggregate
is not affected by the argument onAggregate
.
To disable the generation of actedInAggregate
, see the aggregate
argument of the directive @relationship
.
@settable
This directive sets the availability of the input field on creation and update mutations. It has two arguments:
-
onCreate: if disabled, this field is not available on creation operations.
-
onUpdate: if disabled, this field is not available on update operations.
Definition
"""Instructs @neo4j/graphql to generate this input field for mutation."""
directive @settable(onCreate: Boolean! = true, onUpdate: Boolean! = true) on FIELD_DEFINITION
Usage
With this definition:
type Movie @node {
title: String!
description: String @settable(onCreate: true, onUpdate: false)
}
type Actor @node {
name: String!
actedIn: [Movie!]!
@relationship(type: "ACTED_IN", direction: OUT)
}
The following input fields are generated:
input MovieCreateInput {
description: String
title: String!
}
input MovieUpdateInput {
title: String
}
This means the description can be set on creation, but it is not available on update operations.
@settable
with relationships
This directive can be used along with relationship fields. When an operation on a field is disabled this way, that relationship is no longer available on top-level operations. For example:
type Movie @node {
title: String!
description: String
}
type Actor @node {
name: String!
actedIn: [Movie!]!
@relationship(type: "ACTED_IN", direction: OUT)
@settable(onCreate: false, onUpdate: true)
}
The following input fields are generated:
input ActorCreateInput {
name: String!
}
input ActorUpdateInput {
name: String
actedIn: [ActorActedInUpdateFieldInput!]
}
This means actedIn
can be updated on an update, but it is no longer available on create`
operations.
@filterable
This directive defines the filters generated for the field to which this directive is applied. It has two arguments:
-
byValue: if disabled, this field does not generate value filters.
-
byAggregate: if disabled, this field does not generate aggregation filters.
Definition
"""Instructs @neo4j/graphql to generate filters for this field."""
directive @filterable(byValue: Boolean! = true, byAggregate: Boolean! = true) on FIELD_DEFINITION
Usage
With this definition:
type Movie @node {
title: String!
description: String @filterable(byValue: false, byAggregate: false)
actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN)
}
type Actor @node {
name: String!
actedIn: [Movie!]!
@relationship(type: "ACTED_IN", direction: OUT)
}
The following input fields are generated:
input MovieWhere {
OR: [MovieWhere!]
AND: [MovieWhere!]
NOT: MovieWhere
title_EQ: String
title_IN: [String!]
title_CONTAINS: String
title_STARTS_WITH: String
title_ENDS_WITH: String
actorsAggregate: MovieActorsAggregateInput
actors_ALL: ActorWhere
actors_NONE: ActorWhere
actors_SINGLE: ActorWhere
actors_SOME: ActorWhere
actorsConnection_ALL: MovieActorsConnectionWhere
actorsConnection_NONE: MovieActorsConnectionWhere
actorsConnection_SINGLE: MovieActorsConnectionWhere
actorsConnection_SOME: MovieActorsConnectionWhere
}
input ActorActedInNodeAggregationWhereInput {
AND: [ActorActedInNodeAggregationWhereInput!]
OR: [ActorActedInNodeAggregationWhereInput!]
NOT: ActorActedInNodeAggregationWhereInput
title_AVERAGE_LENGTH_EQUAL: Float
title_LONGEST_LENGTH_EQUAL: Int
title_SHORTEST_LENGTH_EQUAL: Int
title_AVERAGE_LENGTH_GT: Float
title_LONGEST_LENGTH_GT: Int
title_SHORTEST_LENGTH_GT: Int
title_AVERAGE_LENGTH_GTE: Float
title_LONGEST_LENGTH_GTE: Int
title_SHORTEST_LENGTH_GTE: Int
title_AVERAGE_LENGTH_LT: Float
title_LONGEST_LENGTH_LT: Int
title_SHORTEST_LENGTH_LT: Int
title_AVERAGE_LENGTH_LTE: Float
title_LONGEST_LENGTH_LTE: Int
title_SHORTEST_LENGTH_LTE: Int
}
As shown by the generated input fields, the description
field is not available for filtering on both value and aggregation filters.
@filterable
with relationships
This directive can be used along with relationship fields. When an operation on a field is disabled this way, that relationship is no longer available on top-level operations. For example:
type Movie @node {
title: String!
description: String @filterable(byValue: false, byAggregate: false)
actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN) @filterable(byValue: false, byAggregate: false)
}
type Actor @node {
name: String!
actedIn: [Movie!]!
@relationship(type: "ACTED_IN", direction: OUT)
}
The following input fields are generated:
input MovieWhere {
OR: [MovieWhere!]
AND: [MovieWhere!]
NOT: MovieWhere
title_EQ: String
title_IN: [String!]
title_CONTAINS: String
title_STARTS_WITH: String
title_ENDS_WITH: String
}
input ActorActedInNodeAggregationWhereInput {
AND: [ActorActedInNodeAggregationWhereInput!]
OR: [ActorActedInNodeAggregationWhereInput!]
NOT: ActorActedInNodeAggregationWhereInput
title_AVERAGE_LENGTH_EQUAL: Float
title_LONGEST_LENGTH_EQUAL: Int
title_SHORTEST_LENGTH_EQUAL: Int
title_AVERAGE_LENGTH_GT: Float
title_LONGEST_LENGTH_GT: Int
title_SHORTEST_LENGTH_GT: Int
title_AVERAGE_LENGTH_GTE: Float
title_LONGEST_LENGTH_GTE: Int
title_SHORTEST_LENGTH_GTE: Int
title_AVERAGE_LENGTH_LT: Float
title_LONGEST_LENGTH_LT: Int
title_SHORTEST_LENGTH_LT: Int
title_AVERAGE_LENGTH_LTE: Float
title_LONGEST_LENGTH_LTE: Int
title_SHORTEST_LENGTH_LTE: Int
}
As shown by the previous inputs fields, the actors
field is not available for filtering on both value and aggregation filters.