graphql

chrisulloa 2021-03-05T19:44:54.002500Z

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.

chrisulloa 2021-03-05T19:45:06.002800Z

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

chrisulloa 2021-03-05T19:46:24.003600Z

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.

emccue 2021-03-05T20:23:23.004100Z

graphql lets resolvers work in parallel

emccue 2021-03-05T20:23:59.004700Z

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

chrisulloa 2021-03-05T21:14:23.005Z

gotcha makes sense, thanks

chrisulloa 2021-03-05T21:17:16.005500Z

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

chrisulloa 2021-03-05T21:17:24.005800Z

https://lacinia.readthedocs.io/en/latest/resolve/selections.html

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.

mafcocinco 2021-03-05T21:19:06.006500Z

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?

mafcocinco 2021-03-05T21:19:21.006800Z

preferably something that is part of the public api.

mafcocinco 2021-03-08T14:06:33.008100Z

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

hlship 2021-03-10T18:29:05.008900Z

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.

hlship 2021-03-10T18:30:37.009100Z

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.

1
mafcocinco 2021-03-10T18:42:32.009500Z

excellent suggestion.