1

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:

  1. Having a way for a parent resolver to get access to its children's args, or
  2. 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.
Nathan
  • 11
  • 2

0 Answers0