Skip to content

Commit

Permalink
Augment filter argument for nested fields
Browse files Browse the repository at this point in the history
If the field of GraphQL Type maps to an *..n relation (a list) and there is currently no `filter`-argument defined, we now generate it in the augmented schema.
The logic for handling these nested filters is already implementd, so no further code-adjustments are required.

resolves #129
  • Loading branch information
Andy2003 committed Apr 14, 2021
1 parent fc52604 commit e65c8e6
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 9 deletions.
18 changes: 12 additions & 6 deletions core/src/main/kotlin/org/neo4j/graphql/SchemaBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ object SchemaBuilder {

val handler = getHandler(config)

var targetSchema = augmentSchema(sourceSchema, handler)
var targetSchema = augmentSchema(sourceSchema, handler, config)
targetSchema = addDataFetcher(targetSchema, dataFetchingInterceptor, handler)
return targetSchema
}
Expand Down Expand Up @@ -128,7 +128,7 @@ object SchemaBuilder {
return handler
}

private fun augmentSchema(sourceSchema: GraphQLSchema, handler: List<AugmentationHandler>): GraphQLSchema {
private fun augmentSchema(sourceSchema: GraphQLSchema, handler: List<AugmentationHandler>, schemaConfig: SchemaConfig): GraphQLSchema {
val types = sourceSchema.typeMap.toMutableMap()
val env = BuildingEnv(types, sourceSchema)
val queryTypeName = sourceSchema.queryTypeName()
Expand Down Expand Up @@ -157,11 +157,11 @@ object SchemaBuilder {
builder.clearFields().clearInterfaces()
// to prevent duplicated types in schema
sourceType.interfaces.forEach { builder.withInterface(GraphQLTypeReference(it.name)) }
sourceType.fieldDefinitions.forEach { f -> builder.field(enhanceRelations(f, env)) }
sourceType.fieldDefinitions.forEach { f -> builder.field(enhanceRelations(f, env, schemaConfig)) }
}
sourceType is GraphQLInterfaceType -> sourceType.transform { builder ->
builder.clearFields()
sourceType.fieldDefinitions.forEach { f -> builder.field(enhanceRelations(f, env)) }
sourceType.fieldDefinitions.forEach { f -> builder.field(enhanceRelations(f, env, schemaConfig)) }
}
else -> sourceType
}
Expand All @@ -177,7 +177,7 @@ object SchemaBuilder {
.build()
}

private fun enhanceRelations(fd: GraphQLFieldDefinition, env: BuildingEnv): GraphQLFieldDefinition {
private fun enhanceRelations(fd: GraphQLFieldDefinition, env: BuildingEnv, schemaConfig: SchemaConfig): GraphQLFieldDefinition {
return fd.transform { fieldBuilder ->
// to prevent duplicated types in schema
fieldBuilder.type(fd.type.ref() as GraphQLOutputType)
Expand All @@ -192,14 +192,20 @@ object SchemaBuilder {
if (fd.getArgument(ProjectionBase.OFFSET) == null) {
fieldBuilder.argument { a -> a.name(ProjectionBase.OFFSET).type(Scalars.GraphQLInt) }
}
if (fd.getArgument(ProjectionBase.ORDER_BY) == null && fd.type.isList()) {
if (fd.getArgument(ProjectionBase.ORDER_BY) == null) {
(fd.type.inner() as? GraphQLFieldsContainer)?.let { fieldType ->
env.addOrdering(fieldType)?.let { orderingTypeName ->
val orderType = GraphQLList(GraphQLNonNull(GraphQLTypeReference(orderingTypeName)))
fieldBuilder.argument { a -> a.name(ProjectionBase.ORDER_BY).type(orderType) }
}
}
}
if (schemaConfig.query.enabled && fd.getArgument(ProjectionBase.FILTER) == null) {
(fd.type.inner() as? GraphQLFieldsContainer)?.let { fieldType ->
val filterTypeName = env.addFilterType(fieldType)
fieldBuilder.argument(input(ProjectionBase.FILTER, GraphQLTypeReference(filterTypeName)))
}
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions core/src/test/resources/augmentation-tests.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ schema {
}
interface HasMovies {
movies(first: Int, offset: Int, orderBy: [_MovieOrdering!]): [Movie]
movies(filter: _MovieFilter, first: Int, offset: Int, orderBy: [_MovieOrdering!]): [Movie]
}
type Knows0 @relation(direction : OUT, from : "source", name : "KNOWS", to : "knows") {
Expand Down Expand Up @@ -454,7 +454,7 @@ type Person4 {
type Person5 implements HasMovies {
id: ID!
movies(first: Int, offset: Int, orderBy: [_MovieOrdering!]): [Movie] @relation(direction : OUT, from : "from", name : "LIKES", to : "to")
movies(filter: _MovieFilter, first: Int, offset: Int, orderBy: [_MovieOrdering!]): [Movie] @relation(direction : OUT, from : "from", name : "LIKES", to : "to")
}
type Publisher {
Expand All @@ -472,7 +472,7 @@ type Query {
person3(born: _Neo4jLocalTimeInput, filter: _Person3Filter, first: Int, name: String, offset: Int, orderBy: [_Person3Ordering!]): [Person3!]!
person4(born: _Neo4jLocalDateTimeInput, filter: _Person4Filter, first: Int, id: ID, name: String, offset: Int, orderBy: [_Person4Ordering!]): [Person4!]!
person5(filter: _Person5Filter, first: Int, id: ID, offset: Int, orderBy: [_Person5Ordering!]): [Person5!]!
PersonByLocation(first: Int, location: _Neo4jPointInput, offset: Int, orderBy: [_Person0Ordering!]): [Person0!]!
PersonByLocation(filter: _Person0Filter, first: Int, location: _Neo4jPointInput, offset: Int, orderBy: [_Person0Ordering!]): [Person0!]!
publisher(filter: _PublisherFilter, first: Int, name: ID, offset: Int, orderBy: [_PublisherOrdering!]): [Publisher!]!
}
Expand Down

0 comments on commit e65c8e6

Please sign in to comment.