Field configuration
This is the documentation of the GraphQL Library version 7. 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!]!
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!]!
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
, 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
}
directive @relationship(
type: String!
queryDirection: RelationshipQueryDirection! = DEFAULT_DIRECTED
direction: RelationshipDirection!
properties: String
nestedOperations: [NestedOperations!]! = [CREATE, UPDATE, DELETE, CONNECT, DISCONNECT]
aggregate: Boolean! = true
) on FIELD_DEFINITION
Usage
Configure aggregation
From the previous type definitions, the types related to Actor
produced are:
type Actor {
name: String!
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!
}
type ActorActedInConnection {
edges: [ActorActedInRelationship!]!
totalCount: Int!
pageInfo: PageInfo!
aggregate: ActorMovieActedInAggregateSelection!
}
Note that the relationship field actedIn
produces the operation field aggregate
in the type ActorActedInConnection
, 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 ActorActedInConnection
produced is:
type ActorActedInConnection {
edges: [ActorActedInRelationship!]!
totalCount: Int!
pageInfo: PageInfo!
}
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
}
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])
}
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 MovieAggregateNode {
title: StringAggregateSelection!
description: StringAggregateSelection!
}
In case you want to remove the description
field from MovieAggregateNode
, 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!]!
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!
actedInConnection(where: ActorActedInConnectionWhere, first: Int, after: String, directed: Boolean = true, sort: [ActorActedInConnectionSort!]): ActorActedInConnection!
}
type ActorActedInConnection {
aggregate: ActorMovieActedInAggregateSelection!
}
Note how the aggregate
field is still present on the ActorActedInConnection
type, and not affected by the argument onAggregate
.
To disable the generation of the aggregate
field, see the aggregate
argument of the @relationship
directive.
@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: StringScalarMutations
}
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: StringScalarMutations
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: StringScalarFilters
actors: ActorRelationshipFilters
actorsConnection: MovieActorsConnectionFilters
}
input ActorActedInNodeAggregationWhereInput {
AND: [ActorActedInNodeAggregationWhereInput!]
OR: [ActorActedInNodeAggregationWhereInput!]
NOT: ActorActedInNodeAggregationWhereInput
title: StringScalarAggregationFilters
}
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: StringScalarFilters
}
input ActorActedInNodeAggregationWhereInput {
AND: [ActorActedInNodeAggregationWhereInput!]
OR: [ActorActedInNodeAggregationWhereInput!]
NOT: ActorActedInNodeAggregationWhereInput
title: StringScalarAggregationFilters
}
As shown by the previous inputs fields, the actors
field is not available for filtering on both value and aggregation filters.