Repository: graphql-java-kickstart/graphql-java-tools
Pull request #488 (2021-03-09 14:40:59)

Remove error when DataFetcherResult is not the root type
<!-- Uncomment one of the following lines as necessary. -->
<!-- Fixes #<ISSUE_NUMBER> -->
Resolves https://spectrum.chat/graphql-java-kick/tools/list-of-datafetcherresults~9ca373af-c480-4ae5-869a-775ca8f1885e

## Checklist
<!-- Change [ ] to [x] to indicate you acknowledge the check. -->
- [x] Pull requests follows the [contribution guide](https://github.com/graphql-java-kickstart/graphql-java-tools/wiki/Contribution-guide)
- [x] New or modified functionality is covered by tests

## Description
<!-- Briefly describe how you resolved the issue or a bug. -->
graphql-java supports lists of DataFetcherResult.

This PR remove error when DataFetcherResult is not the root return type


Patch:
diff --git a/src/main/kotlin/graphql/kickstart/tools/TypeClassMatcher.kt b/src/main/kotlin/graphql/kickstart/tools/TypeClassMatcher.kt
index 4f4a460..840c4a1 100644
--- a/src/main/kotlin/graphql/kickstart/tools/TypeClassMatcher.kt
+++ b/src/main/kotlin/graphql/kickstart/tools/TypeClassMatcher.kt
@@ -32,10 +32,6 @@ internal class TypeClassMatcher(private val definitionsByName: Map<String, TypeD
                 throw error(potentialMatch, "${DataFetcherResult::class.java.name} can only be used as a return type")
             }
 
-            if (!root) {
-                throw error(potentialMatch, "${DataFetcherResult::class.java.name} can only be used at the top level of a return type")
-            }
-
             realType = potentialMatch.generic.unwrapGenericType(realType.actualTypeArguments.first())
 
             if (realType is ParameterizedType && potentialMatch.generic.isTypeAssignableFromRawClass(realType, DataFetcherResult::class.java)) {


Test patch:
diff --git a/src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt b/src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt
index e9480e4..8047a1a 100644
--- a/src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt
+++ b/src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt
@@ -76,6 +76,7 @@ type Query {
 
     propertyField: String!
     dataFetcherResult: Item!
+    dataFetcherResultItems: [Item!]!
 
     coroutineItems: [Item!]!
 
@@ -302,6 +303,10 @@ class Query : GraphQLQueryResolver, ListListResolver<String>() {
         return DataFetcherResult.newResult<Item>().data(items.first()).build()
     }
 
+    fun dataFetcherResultItems(): List<DataFetcherResult<Item>> {
+        return listOf(DataFetcherResult.newResult<Item>().data(items.first()).build())
+    }
+
     suspend fun coroutineItems(): List<Item> = CompletableDeferred(items).await()
 
     fun arrayItems() = items.toTypedArray()
@@ -329,7 +334,7 @@ class Mutation : GraphQLMutationResolver {
     }
 
     fun saveUser(userInput: UserInput): String {
-        return userInput.name + "/" + userInput.password;
+        return userInput.name + "/" + userInput.password
     }
 
     class UserInput {
diff --git a/src/test/kotlin/graphql/kickstart/tools/EndToEndTest.kt b/src/test/kotlin/graphql/kickstart/tools/EndToEndTest.kt
index b67d697..6ca764c 100644
--- a/src/test/kotlin/graphql/kickstart/tools/EndToEndTest.kt
+++ b/src/test/kotlin/graphql/kickstart/tools/EndToEndTest.kt
@@ -532,6 +532,21 @@ class EndToEndTest {
         assertEquals(data["dataFetcherResult"], mapOf("name" to "item1"))
     }
 
+    @Test
+    fun `generated schema supports list of DataFetcherResult`() {
+        val data = assertNoGraphQlErrors(gql) {
+            """
+            {
+                dataFetcherResultItems {
+                    name
+                }
+            }
+            """
+        }
+
+        assertEquals(data["dataFetcherResultItems"], listOf(mapOf("name" to "item1")))
+    }
+
     @Test
     fun `generated schema supports Kotlin suspend functions`() {
         val data = assertNoGraphQlErrors(gql) {