pathom

:pathom: https://github.com/wilkerlucio/pathom/ & https://pathom3.wsscode.com & https://roamresearch.com/#/app/wsscode
Mark Wardle 2021-04-21T07:32:25.208700Z

Hi all. A style question really. Is it reasonable to use defmutation to define an action that doesn’t really change state? I’d like to leverage pathom as the principal API across multiple backend services including operations such as search or login. I guess the latter might change state - eg audit trail - but search is idempotent. What’s the ‘best’ way?

wilkerlucio 2021-04-21T12:40:33.211200Z

yes, no problems using mutations like that, I see mutations as “commands”. while attributes are about getting some piece of data, mutations are about telling something to happen, its ok if they dont change state

👍 1
💯 1
Mark Wardle 2021-04-21T12:45:54.212200Z

Thank you Wilker!

wilkerlucio 2021-04-21T12:47:53.213900Z

altough search is the most gray area here, because its asking for data more than asking a command, but Im not the police, do whatever works for you :)

👍 1
prnc 2021-04-21T17:25:56.214600Z

Hi 👋 A small question about attribute nesting. I came across this today, trying out pathom3.

prnc 2021-04-21T17:26:07.214900Z

(pco/defresolver foo [{input :input}]
    {:foo
     {:msg (str "Foo: Hello, " input)}})

   (pco/defresolver bar [] ;; no dependencies
     {:bar "This is bar"})

   (def env
     (pci/register [foo bar]))

   (p.eql/process env
                  {:input "World"}
                  [{:foo [:bar]}])

   ;; => {:foo {:bar "This is bar"}}
   
   ;; BUT with...

   (pco/defresolver bar [{foo :foo}] ;; depends on :foo
     {:bar "This is bar"})

   (p.eql/process env
                  {:input "Hello"}
                  [{:foo [:bar]}])
   ;; => {:foo {}}

prnc 2021-04-21T17:26:34.215100Z

I was trying to “further resolve” attribute by pulling from db (datomic). Additional data would be nested in what I already have like :bar in the example. But this doesn’t seem to work when :bar depends on the parent key (:foo here). Nesting works fine when :bar has no dependencies. Is there a way around this or maybe there are good reasons for this and it’s the intended behaviour ;)?

markaddleman 2021-04-21T17:42:44.217100Z

I'm a heavy user of pathom3 and I've run into a number of bugs related to @wilkerlucio latest post https://blog.wsscode.com/pathom-updates-09/ . I don't know but I suspect you are running into a planner bug. fwiw, the following resolver will produce a result

(pco/defresolver foo-bar [{_ :input}]
  {:foo {:bar "This is bar"}})

🙏 1
markaddleman 2021-04-21T17:46:30.217500Z

@prnc ^^

wilkerlucio 2021-04-21T17:49:18.217600Z

Pathom is doing the expected stuff in this example

wilkerlucio 2021-04-21T17:49:43.217800Z

on the second case, where :bar depends on :foo, at that context you asked :bar, there is no :foo

wilkerlucio 2021-04-21T17:49:49.218Z

Pathom looks at each entity level

wilkerlucio 2021-04-21T17:50:03.218200Z

the parent entity has :foo, but that’s not where you are asking for it

wilkerlucio 2021-04-21T17:50:28.218400Z

(p.eql/process env
                  {:input "Hello"}
                  [:foo :bar])

wilkerlucio 2021-04-21T17:50:42.218600Z

in this case ☝️ they are siblings, so :bar can see :foo, and that’s valid

wilkerlucio 2021-04-21T17:50:56.218800Z

but you can’t ask for parent attributes

wilkerlucio 2021-04-21T17:52:27.219100Z

yes, it is intended behavior

wilkerlucio 2021-04-21T17:52:59.219400Z

dependencies are across the same entity, and with Pathom 3 there is support for nested requires (goes down), but never going up (looking at parent)

wilkerlucio 2021-04-21T17:53:18.219600Z

for Pathom, each map is an indepent entity, if we pulled data from all parents would be just crazy 😛

wilkerlucio 2021-04-21T17:54:11.219900Z

if a parent information is intended to be used on the children, the resolver that provides the children must pass it forward

wilkerlucio 2021-04-21T17:55:31.220100Z

hey @markaddleman, curious, did you tried upgrading to the version after the post? did you still see these kind of bugs after?

wilkerlucio 2021-04-21T17:55:49.220300Z

(and to clarify, in the case of prnc, its not a bug)

👍 1
prnc 2021-04-21T17:56:07.220500Z

Haha, fair enough! Need to get my intuition around how things work in pathom a little stronger. Initially I was thinking it’s similar in philosophy to spec/rdf w/ global, “strongly namespaced” attributes

prnc 2021-04-21T17:56:38.220700Z

…and then resolvers sitting between them, i.e. edges: I have A and want B

markaddleman 2021-04-21T17:56:41.220900Z

Funny you should bring that up. I just tried upgrading to the latest commit and ran into some problems. I was just about to ask you if the latest commit contained fixes to the shared attribute problem that you describe in your post 🙂

markaddleman 2021-04-21T17:58:48.221100Z

In short, I have an attribute that is used by a couple of resolvers that share a parent child relationship. These parent resolver is probably three levels deep in the larger planning tree.

markaddleman 2021-04-21T18:00:16.221300Z

If I remove the common attribute from the input of one of the resolvers, the plan is generated. However, if the attribute is in the input of both resolvers, no plan in generated

markaddleman 2021-04-21T18:00:47.221500Z

I don't have a good way of creating a small reproducible case

wilkerlucio 2021-04-21T18:01:03.221700Z

I also did one fix yesterday related to nested queries

wilkerlucio 2021-04-21T18:01:18.221900Z

with the new planner I expect to have none (or very few) bugs related to flat queries

wilkerlucio 2021-04-21T18:01:37.222100Z

but I still need to get the generators to make nested cases, them the confidence on those can increase as well

markaddleman 2021-04-21T18:03:16.222300Z

gotcha. For now, I am working with an older commit and several of my resolvers must perform p.eql/process explicitly rather than depend on inputs. It's a good enough approach for my needs 🙂

wilkerlucio 2021-04-21T18:03:58.222500Z

it is, one thing to help is remember to isolate the context in one entity, the parent example, is like this: A has :foo, which is an entity (lets call it B), now I navigate to entity B and ask :bar from it, now why I can’t find :foo in B?

markaddleman 2021-04-21T18:04:40.222700Z

If it would be helpful, I'd be happy to screenshare my code so you can see firsthand the problem with the latest commit. Maybe do that after you get the generators to make nested cases and you have a chance to work out those bugs.

wilkerlucio 2021-04-21T18:04:45.222900Z

any time you navigate to a new map, is like navigating to a new entity in the graph

wilkerlucio 2021-04-21T18:04:53.223100Z

makes sense?

prnc 2021-04-21T18:07:22.223400Z

Thanks @wilkerlucio — just for context of this, to make it slightly more practical: I was wondering how one could replicate datomic pull behaviour in which e.g. in pathom say I get {:media/uri {:db/id 2344534545}} from some resolver and the request to pathom is [{:media/uri [:uri/host]}] and :uri/host could be resolved based on that :db/id if requested like above. So in my mind the resolver returning {:uri/host} would depend on the parent of {:media/uri ,,, } , no?

wilkerlucio 2021-04-21T18:09:11.223600Z

no, :uri/host should depend on :db/id

wilkerlucio 2021-04-21T18:09:28.223800Z

so using a :db/id you fetch the entity and read the :uri/host from it

prnc 2021-04-21T18:11:09.224100Z

I see, that makes a lot of sense.

prnc 2021-04-21T18:19:34.224300Z

Thanks so much! Now let me experiment some more and get a better understanding before I tire you too much with all that 😜

wilkerlucio 2021-04-21T18:57:57.224500Z

no worries, have fun 🙂