Fork me on GitHub
#graphql
<
2018-03-19
>
hlship13:03:55

It's actually the other way around; the parents execute first and can gain information about what will be resolved beneath them.

hlship13:03:45

In addition, parents can place extra data into the context that is only available to children (and grandchildren, etc.).

hlship13:03:17

So anything useful needed by (grand-)children that can't be simply assoc'ed onto the resolved value can instead by passed int the context.

tbaldridge15:03:45

Let me ask in a bit more detail. Let's assume I have people and pets (to use the overused example) and my query is "get all people and pets where the person's name is "John"". I assume my person resolver will be hit first with "name=John".

tbaldridge15:03:05

Then does it make a single call to "get_pets" passing in all the IDs of the people?

tbaldridge15:03:41

@hlship in other words, does Lacinia do the hash-join or do I have to do that manually.

hlship16:03:07

Ah, yes, the N+1 problem. Lacinia doesn't do anything here, and the naive implementation of get_pets will execute N times for the N users.

hlship16:03:40

The right approach is to have the get_users resolver use the http://lacinia.readthedocs.io/en/latest/resolve/selections.html#previewing-selections preview API to see that pets are part of the client's request. It can do the join query on pets while it is fetching users, and organize all that into a map, placed into the context: http://lacinia.readthedocs.io/en/latest/resolve/selections.html#previewing-selections

hlship16:03:45

So we end up boosting the queries upwards in the tree (the top level query being the root), and lower-level resolvers are just unpackaging data placed into the context by the (grand-)parent resolvers.

hlship16:03:32

We haven't seen this to be a big problem because we use Cassandra 😞

hlship16:03:34

so there's no concept of a join query, and large numbers of parallel short queries are actually better

hlship16:03:47

but Lacinia tries to stay out of the way for solutions against more traditional SQL stores

hlship16:03:26

The tutorial is written using PostgreSQL and I'll eventually get to this issue.

hlship16:03:34

But that raises an interesting thought; as currently implement, there's explicit code that, when selecting with a list type (such as the list of users from the get_users resolver), acts like a map operation on the individual values, so the child resolvers (`get_pets`) just sees one user at a time.

hlship16:03:38

But I could envision an alternative where the list of users is passed to get_pets, which can return ... something? I literally typed to that point and realized I don't have a good solution, since Lacinia doesn't have any concept of a 'record key' to tie things together.

tbaldridge16:03:23

@hlship that helps a lot, thanks! I have code that does that sort of optimization so layering lancinia on top isn't going to be hard. And frankly, I'm a bit happy that I didn't rewrite something that already exists in a library.

danielneal11:03:15

"code that does that sort of optimization" <- that sounds interesting. Is that all private stuff?

tbaldridge16:03:56

But yes, it requires some concept of a foreign key.

hlship17:03:40

That's pretty much our goal for lacinia, have it do what makes sense and not anything extra.