I'm using Node.js Apollo Server (4.3.0) to return fairly complex GraphQL. Greatly simplified here, I have an Connection
of Child
objects that can be queried directly, as well as a Connection
of Parent
objects that can contain the same ChildConnection
.
type Query {
parentQuery(first: Int, after: String): ParentConnection
childQuery(first: Int, after: String): ChildConnection
}
type ParentConnection: {
edges: [ParentEdge!]
pageInfo: PageInfo
}
type ParentEdge: {
node: Parent
cursor: String
}
type Parent: {
children(first: Int, after: String): ChildConnection
}
type ChildConnection: {
edges: [ChildEdge!]
pageInfo: PageInfo
}
type ChildEdge: {
node: Child
cursor: String
}
type Child {
id: ID!
}
The issue arises when calling parentQuery
, asking for the whole tree. Sometimes the children
field for a particular Parent
has no edges, and is not useful to send to a client. I would like to omit this ParentEdge
from the query response, rather than stripping it on the client-side which seems wasteful and error-prone.
In Apollo server this would usually be fine - call directly down to your resolver tree, await the results, return null for the parent or simply don't add it to the Connection. The complication here is that the ChildConnection
takes the usual Connection
args, and in Apollo Server, the args for a child are not available to the parent. Thus, attempting to resolve the tree from the ParentConnection
level will ignore the ChildConnection
args. Attempting to resolve the tree from the Parent
level, at most allows you to modify the ParentEdge
resolver via the parent
field, leaving you with empty entries in the ParentConnection.edges
field.
Hoisting the args from the children
field of the Parent
to the parentQuery
would solve the problem, but it would be designing the schema to match the implementation, rather than following connection best-practices.
The two clean solutions in my mind are:
- Having a way for a parent resolver to get access to its children's args, or
- Having a way in to perform processing on a resolver AFTER its entire tree has been resolved. Even potentially after the entire query has been completed.