Fork me on GitHub
#pathom
<
2021-01-25
>
imre09:01:22

Hey Wilker, I was wondering if you could point me in the right direction with this.

{:foo/people
 [:foo.person/name
  :foo.person/age
  :foo.person/family-tree]}
Imagine the above. I am trying to wrap a library call which is roughly (input, calculate-family-tree?) -> people. Now, family tree calculation is expensive, so when it is not needed, I'd like to pass false there. Is this solvable only by looking at the query itself in the resolver, or is it possible to make this work by writing multiple resolvers with different output definitions, one resolver also returning family trees, the other not. The aim is that there is only one call made to the lib and calculate-family-tree? is false where we don't need to return it.

dehli13:01:02

If you have a resolver that only outputs :foo.person/family-tree and then another resolver for the other attributes I think that would solve the issue. If the client doesn’t specify family-tree in the query, then pathom won’t execute the expensive query. Does this answer the question?

imre13:01:33

I'm not sure that would work. Clients either want [name age family-tree] or [name age].

imre13:01:56

And while family-tree is the most expensive to calculate, the other 2 are also somewhat costly, so we only want to make one call to the underlying lib. Retrieving family-tree separately from the other 2 won't work for us I'm afraid.

imre14:01:26

One alternative we considered was to make 2 top-level keys, :foo/people and :foo/people-with-family-tree, which works but feels a little clunky.

wilkerlucio19:01:46

hello @U08BJGV6E, not sure if I got it right, but the thing you say is that to compute :foo/people you like to know ahead of time if the user asked for family-tree in the sub?

wilkerlucio19:01:06

my normal reaction to this would be to have one resolver for each attribute there (name, age, family tree)

wilkerlucio19:01:56

the only case I think you really need to see it before is that if your sub request depends on it, in this case its more like Datomic or GraphQL integrations (where we need to figure what parts of the sub-query must be delegated), does this sounds like your case?

imre19:01:55

One resolver per attr would be best, yes, but the library we are wrapping returns all 3 of these in one call getpeople(input, family-tree?) -> people

imre19:01:21

and the call is expensive, and even more expensive if we tell it to also return the family tree

imre19:01:34

so regardless of the desired output (whether it's a single prop or all 3) we only want to make one lib call per request

imre19:01:08

and when the request doesn't specify family-tree as output, pass false to the lib call so it isn't calculated

wilkerlucio19:01:49

gotcha, that to me aligns a lot on how dynamic resolvers work, this is something I'll work more once the tools and basics are out

wilkerlucio19:01:04

for now, like you said, you can look at the ast and make this decision

wilkerlucio19:01:25

I think I did something similar for the Youtube API, where they accept the "parts" to say which pieces you want, in this case I also look at the query to decide it

wilkerlucio19:01:46

what's really tricky is if you don't depend on this attribute directly, but instead you are trying to get some attribute that depends on it

wilkerlucio19:01:54

on this case, the simple lookup on the AST wouldn't be enough

wilkerlucio19:01:11

that's where dynamic resolvers will be really helpful, because they can do these attribute calculations for you (and it does it at the same planning phase as the static resolvers stuff)

imre19:01:54

Gotcha, thank you. What do you think about the approach where we'd have 2 resolvers, one returning {:foo/people [:name :age]} and another returning {:foo/people-with-tree [:name :age :tree]}?

imre19:01:15

I wonder if you'd consider this more or less fragile in terms of composition than the look-at-ast way?

wilkerlucio19:01:18

are you in pathom 2 or 3?

wilkerlucio19:01:52

I think you can do with two resolvers, but you would need pathom 3, to set the resolver priority

wilkerlucio19:01:10

also, pathom 2 doesnt look at subqueries for process, pathom 3 does

imre19:01:26

I see. Thank you for the insight!

wilkerlucio19:01:40

so {:foo/people [:name :age]} needs to have higher priority if you do it this way

wilkerlucio19:01:11

if you use different names foo/people and foo/people-with-tree, that works fine (in pathom 2 or 3)

wilkerlucio19:01:27

if you don't mind having this caveat for your interface, its good

Janos19:01:58

Hey Wilker, I've been trying to use this helper fn for the dynamic resolver for this problem: https://github.com/wilkerlucio/pathom/blob/master/src/com/wsscode/pathom/connect.cljc#L670

Janos19:01:43

Unfortunately we would need nested attributes in the response like in your latest example {:foo/people [:name :age]}

Janos19:01:40

For this query that fn would only return :foo/people attribute

Janos19:01:42

But I guess I could write some custom code 😊

wilkerlucio20:01:34

yeah, if you need, go forward, Pathom 2 isn't getting any updates on the dynamic side of things, and for Pathom 3 things are quite different, so whatever happens in Pathom 3 is gonna be different from what you looking at now

👍 3
wilkerlucio21:01:53

hello people! for the adventurous, the new Pathom Viz with trace support for Pathom 3 is out 🎉! You can download it at: https://github.com/wilkerlucio/pathom-viz/releases/tag/v2021.1.25, remember to use the latest connector and pathom 3 as well. Documentation around debugging (with and without Pathom Viz) is my next task, should be out later this week! Even if you don't use Pathom 3 yet, I recommend upgrading, I updated the views with Clojure readonly to use the new Clojure-mode from nextjournal, and its great! the biggest difference for me is that it supports folding, and when looking at big structures that's a big deal. Also I made all the printed maps to be sorted, making easier to find the data. Remember Pathom Viz is compatible with both Pathom 2 and 3. Please let me know if have any issues with this release.

🎉 9
👏 3