spring-projects / spring-graphql

Spring Integration for GraphQL
https://spring.io/projects/spring-graphql
Apache License 2.0
1.5k stars 297 forks source link

TypeMismatchError if controller method returning `Flow` is declared without suspend keyword #988

Closed hantsy closed 3 weeks ago

hantsy commented 1 month ago

I tried to update my example project to use Flow, Spring Boot 3.3.0/Spring GraphQL 1.3 includes the Kotlin Flow type support.

@QueryMapping
fun allPosts(): Flow<Post> = postService.allPosts()// remove .toList() to return Flow type directly

But run the following tests in the QueryTests.

@Test
fun `get all posts`() = runTest {
    coEvery { postService.allPosts() } returns
            flowOf(
                Post(
                    id = UUID.randomUUID(),
                    title = "Post 1",
                    content = "Post 1 content",
                    status = PostStatus.DRAFT,
                    createdAt = LocalDateTime.now()
                ),
                Post(
                    id = UUID.randomUUID(),
                    title = "Post 2",
                    content = "Post 2 content",
                    status = PostStatus.DRAFT,
                    createdAt = LocalDateTime.now()
                )
            )
    val query = "{ allPosts { title content }}"
message: ${error.message}") } }
    graphQlTester.document(query)
       .execute()
       .path("data.allPosts[*].title")
       .entityList(String::class.java).hasSize(2).contains("POST 1", "POST 2")

    coVerify(exactly = 1) { postService.allPosts() }
}

And I got the error [TypeMismatchError{path=[allPosts], expectedType=[Post!]}].

The example project here: https://github.com/hantsy/spring-graphql-sample/tree/master/spring-graphql-rsocket-kotlin-co

https://github.com/spring-projects/spring-graphql/issues/954 resolved the Flow return type, it should support Flow in @QueryMapping also.

rstoyanchev commented 1 month ago

It works when the method is declared with suspend, but not without.