-
Notifications
You must be signed in to change notification settings - Fork 329
Description
tl dr: Is the code in the sample project a good or bad solution for handling RelayConnections wrapped by a union? It uses a solution similar to the existing ConnectionFieldTypeVisitor
.
Problem Description
Relay Pagination is supported in Spring Boot GraphQL so that in the following schema the integers
field will work correctly, but the integersUnion
field will not.
You can get a sample project here here: https://github.com/starJammer/spring-graphql-unions-pagination
The project's README.md file contains the everything I've written below as well.
The sample project includes the proposed solution below so it can be looked at in code.
You can start the sample project and see that no results are returned. (sample query and results below). You can also run the unit tests to check.
type Query {
""" returns a list of integers from 1 to 1000 """
integers(first: Int, after: String): IntegerConnection!
""" Same as above except the connection object is wrapped in a union """
integersUnion(first: Int, after: String): IntegerResult!
}
union IntegerResult = IntegerConnection | NoIntegersFound
type IntegerConnection {
edges: [IntegerEdge]
pageInfo: PageInfo
}
type NoIntegersFound {
message: String!
}
type IntegerEdge {
node: Int
cursor: String
}
type PageInfo {
startCursor: String
endCursor: String
hasNextPage: Boolean
hasPreviousPage: Boolean
}
# Sample query
query Integers {
integersUnion {
__typename
... on IntegerConnection {
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
}
edges {
node
}
}
... on NoIntegersFound {
message
}
}
}
There is no error but the service doesn't return any data. Instead it returns this:
{
"data": {
"integersUnion": {
"__typename": "IntegerConnection",
"pageInfo": null,
"edges": null
}
}
}
The unit test fails with this at the high level and I included the detailed error below:
IntegersGraphQlControllerTest > generateUnionIssue() FAILED
java.lang.AssertionError at IntegersGraphQlControllerTest.kt:67
Caused by: java.lang.AssertionError at IntegersGraphQlControllerTest.kt:67
java.lang.AssertionError: No value at JSON path "$.data.integersUnion.edges"
Request: document='query Integers {
integersUnion {
__typename
... on IntegerConnection {
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
}
edges {
node
}
}
... on NoIntegersFound {
message
}
}
}'
.....
This is the expected result (notice that the edges array is not null):
{
"data": {
"integersUnion": {
"__typename": "IntegerConnection",
"pageInfo": {
"startCursor": "S19bImphdmEudXRpbC5Db2xsZWN0aW9ucyRVbm1vZGlmaWFibGVNYXAiLHsic3RhcnQiOjF9XQ==",
"endCursor": "S19bImphdmEudXRpbC5Db2xsZWN0aW9ucyRVbm1vZGlmaWFibGVNYXAiLHsic3RhcnQiOjEwfV0=",
"hasNextPage": true,
"hasPreviousPage": false
},
"edges": [
{
"node": 1
},
{
"node": 2
},
{
"node": 3
},
{
"node": 4
},
{
"node": 5
},
{
"node": 6
},
{
"node": 7
},
{
"node": 8
},
{
"node": 9
},
{
"node": 10
}
]
}
}
}
Solution Description
Open the GraphQLUnionConfiguration.kt
file in the project and go to line 23 and uncomment it so the bean gets created. (make sure to uncomment or add the related import too at the top of the file).
Run the unit tests again you'll see they succeed. You can also run the service and attempt the query again and notice that it works. (or it should the last time I tested)
If you pass in a negative first
value you will see that the NoIntegersFound
object is returned instead of an IntegerConnection
.
GraphQLUnionConfiguration
will register the ConnectionUnderUnionTypeVisitor
I created in the project.
Read comments on the class for more details but in short it will:
- Look for union types being returned and in a decorator data fetcher.
- The decorator data fetcher will execute the original data fetcher and if the return value
is aSliceWrapper
orWindowWrapper
it will adapt the return value to aConnection
object
the same way thatConnectionFieldTypeVisitor
does. It also adds a type resolver for the union
so it resolves the connection object to the Connection type.
Limitations:
- Does not support multiple connection objects under a union.
- Not sure if this is a good approach or if there is a better one.