Fork me on GitHub

Has anyone encountered an issue with Lacinia where if you have arguments to a field, the resolver is asynchronous, and the parent resolver is asynchronous, the parent and child execute in parallel? I have a child resolver that depends on the parent to pass down context values, but when the child is asynchronous and has arguments the execution order is not what I expect it to be.


I’m thinking maybe this is part of the GraphQL spec, but I haven’t been able to track it down.


Normally it waits for the parent to resolve before resolving the child even when both are async, but adding arguments to the field resolver causes that to change.


graphql lets resolvers work in parallel


i think its part of the spec that order of execution for queries is undefined


gotcha makes sense, thanks


This is the part of the Lacinia docs I read that I thought suggested it would happen in the order I stated above


In execution order, resolution occurs top to bottom, so the hero selection occurs first, then (potentially in parallel) friends, home_planet, and (hero) name. These last two are leaf nodes, because they are scalar values. The list of characters (from the friends field) then has its name field selected. The result map then constructs from bottom to top.


is there a key in the context (or maybe something in the selection protocols) that allows a resolver to find out what query/mutation/subscription it was invoked from?


preferably something that is part of the public api.


Nothing like this currently exists. I’m very curious how this would be useful.


Generally, if children need information from a higher level, a parent resolver puts data into the context that is passed down to children.


yeah, that will work. Can just leave bread crumbs that way.


Also, if it's a parent resolver and immediate child resolver, then just stuff the extra data into the resolved value (probably using namespaced keys to avoid any conflicts). It's only when operating at a further remove that the context approach makes sense.


An example: we collect a search term from a field argument in our root query operation; that goes into the context, because we need it a couple of layers deeper when we're filtering items by the search key. There's (in our app) layers of orders, and item groups, between the query operation resolver, and the matching items resolver that actually needs the search key.

thumbsup_all 3

excellent suggestion.