PropertySelection nests within Connection/edges/node

Closes gh-723
This commit is contained in:
rstoyanchev
2023-06-20 10:05:52 +01:00
parent 6e1e9b76db
commit f383835127
2 changed files with 93 additions and 0 deletions

View File

@@ -23,6 +23,7 @@ import java.util.List;
import java.util.function.Function;
import graphql.schema.DataFetchingFieldSelectionSet;
import graphql.schema.GraphQLNamedOutputType;
import graphql.schema.SelectedField;
import org.springframework.data.mapping.PropertyPath;
@@ -83,6 +84,12 @@ class PropertySelection {
String propertyName = selectedField.getName();
TypeInformation<?> propertyTypeInfo = typeInfo.getProperty(propertyName);
if (propertyTypeInfo == null) {
if (isConnectionEdges(selectedField)) {
getConnectionPropertyPaths(typeInfo, selection, pathFactory, selectedField, result);
}
else if (isConnectionEdgeNode(selectedField)) {
getConnectionPropertyPaths(typeInfo, selection, pathFactory, selectedField, result);
}
continue;
}
@@ -102,6 +109,30 @@ class PropertySelection {
return result;
}
private static boolean isConnectionEdges(SelectedField selectedField) {
return selectedField.getName().equals("edges") &&
selectedField.getParentField().getType() instanceof GraphQLNamedOutputType namedType &&
namedType.getName().endsWith("Connection");
}
private static boolean isConnectionEdgeNode(SelectedField selectedField) {
return selectedField.getName().equals("node") && isConnectionEdges(selectedField.getParentField());
}
private static void getConnectionPropertyPaths(
TypeInformation<?> typeInfo, FieldSelection selection, Function<String, PropertyPath> pathFactory,
SelectedField selectedField, List<PropertyPath> result) {
FieldSelection nestedSelection = selection.select(selectedField);
if (!nestedSelection.isEmpty()) {
TypeInformation<?> actualType = typeInfo.getRequiredActualType();
List<PropertyPath> paths = getPropertyPaths(actualType, nestedSelection, pathFactory);
if (!CollectionUtils.isEmpty(paths)) {
result.addAll(paths);
}
}
}
/**
* Hierarchical representation of selected fields. Allows traversing the

View File

@@ -0,0 +1,62 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.graphql.data.query;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingFieldSelectionSet;
import org.junit.jupiter.api.Test;
import org.springframework.data.util.TypeInformation;
import org.springframework.graphql.BookSource;
import org.springframework.graphql.GraphQlSetup;
import org.springframework.graphql.execution.ConnectionTypeDefinitionConfigurer;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Unit test for {@link PropertySelection}.
*
* @author Rossen Stoyanchev
*/
public class PropertySelectionTests {
@Test
void propertySelectionWithConnection() {
AtomicReference<DataFetchingFieldSelectionSet> ref = new AtomicReference<>();
DataFetcher<?> dataFetcher = environment -> {
ref.set(environment.getSelectionSet());
return null;
};
GraphQlSetup.schemaResource(BookSource.paginationSchema)
.typeDefinitionConfigurer(new ConnectionTypeDefinitionConfigurer())
.dataFetcher("Query", "books", dataFetcher)
.toGraphQlService()
.execute(BookSource.booksConnectionQuery(""))
.block();
TypeInformation<Book> typeInfo = TypeInformation.of(Book.class);
List<String> list = PropertySelection.create(typeInfo, ref.get()).toList();
assertThat(list).containsExactly("id", "name");
}
}