pathom

:pathom: https://github.com/wilkerlucio/pathom/ & https://pathom3.wsscode.com & https://roamresearch.com/#/app/wsscode
wilkerlucio 2021-01-08T02:27:33.105600Z

and to start the good year, another processing feature: now Pathom 3 supports optional inputs! https://pathom3.wsscode.com/docs/resolvers/#optional-inputs

7šŸ‘
souenzzo 2021-01-08T11:40:44.108Z

@wilkerlucio in situations like

;; resolver 1
{:input [:a :b]
 :ouput [:c]}
;; resolver 2
{:input [:a]
 :ouput [:c]}
;; entity
{:a 1 :b 2}
Will resolver 1 *always* be called? If possible, answer both in pathom2 and pathom3 šŸ˜œ

wilkerlucio 2021-01-08T12:08:02.108100Z

quick answer: no

wilkerlucio 2021-01-08T12:08:31.108400Z

in pathom2 that depends on the resolver weight, whatever Pathom things is the faster path, it will take it

wilkerlucio 2021-01-08T12:09:18.108600Z

in pathom3 there still no prioritization yet (altough that's the next thing I'll be working on), so in Pathom 3 its kind random, but will always be same, for now

1šŸ‘
2021-01-08T15:13:00.110800Z

@wilkerlucio will there be an alternative for :com.wsscode.pathom.core/not-found on pathom3? starting to migrate a green field app to pathom3 and we are really happy with the simplicity šŸ™‚

wilkerlucio 2021-01-08T15:15:31.112800Z

@jmayaalv the alternative is check if the key is in the response, in case of not-found, the attribute is gonna be absent, I guess that can solve for most cases, if not, troubleshooting will come as an extension of the new "run stats" thing, hard to explain in brief, but there you can find most data needed to figure any situation, you can take a look at that by checking the meta on the responses (for EQL interface)

wilkerlucio 2021-01-08T15:23:20.116500Z

important thing to take note: each response map has its on run stats (each is a different run context), so if you have a response like {:foo {:bar "baz"}}, there are 2 run stats, one for the outermost map, and one for the inner, in cases of collections, each entry has its own stats

2021-01-08T15:24:05.117300Z

i will check the plugins out, although absent of value should be good enough for us. Thank you !

1šŸ‘
imre 2021-01-08T15:42:45.117900Z

Is there any way for a resolver to set a parameter on one of its outputs?

wilkerlucio 2021-01-08T15:47:21.118100Z

what you mean set a parameter on its outputs?

imre 2021-01-08T15:47:51.118400Z

just trying to come up with a proper example šŸ™‚

imre 2021-01-08T15:56:03.118900Z

so, assuming I have the following resolver:

imre 2021-01-08T15:56:08.119100Z

(pc/defresolver output-resolver
  [env {value :foo/intermediate}]
  {::pc/input  #{:foo/intermediate}
   ::pc/output [:foo/output]}
  {:foo/output [value (-> env :ast :params :some-param)]})

imre 2021-01-08T15:56:32.119300Z

I can use the query

[{[:foo/intermediate 123]
  [(:foo/output {:some-param "value"})]}]

imre 2021-01-08T15:56:59.119500Z

and get {:foo/output [123 "value"]} back

imre 2021-01-08T15:57:20.119700Z

(not guaranteed to be correct, I'm just typing this into a text editor)

imre 2021-01-08T15:57:44.119900Z

I want to create an intermediate resolver, like

(pc/defresolver intermediate-resolver
  [_ {value :foo/input}]
  {::pc/input  #{:foo/input}
   ::pc/output [:foo/intermediate]}
  {:foo/intermediate value})

imre 2021-01-08T15:58:39.120100Z

And within this resolver I want to determine a value for :some-param and pass it on to output-resolver

imre 2021-01-08T16:00:14.120300Z

so a query of `[{[:foo/input 123] [:foo/output]}]` could return {:foo/output [123 "value-set-by-intermediate-resolver"]}

wilkerlucio 2021-01-08T16:02:35.120500Z

no, you can't change things like this sideways, if you need information to flow, add new attributes to the system, make the output of the resolver respond with more keys, and use those keys in the input forward, makes sense?

imre 2021-01-08T16:24:16.120700Z

It does I guess, I primarily just wanted to find out whether it was possible. So for example, if there's a resolver that supports pagination via a parameter, and some other resolver wants to call it with pagination, then pagination will need to be made an input. Is that correct?

csgero 2021-01-08T16:27:36.120900Z

for context, this came up while experimenting with foreign-resolvers, and the second resolver is actually implemented in a different service

2021-01-08T16:28:25.121800Z

Has anyone here used Pathom as a Dependency Injection framework like @souenzzo did here? https://github.com/souenzzo/souenzzo.github.io/blob/master/conduit/src/br/com/souenzzo/conduit/ssr.clj#L270

2021-01-08T16:28:50.122500Z

Any thoughts about using it? (pathom2 examples could be interesting too šŸ™‚ )

2021-01-08T16:29:16.123100Z

I'm looking for a db component + http component service just to example šŸ˜„

2021-01-08T16:29:37.123600Z

I'll do some comparison between Integrant and this approach

2021-01-08T16:29:49.124Z

I was looking for some tips about this

wilkerlucio 2021-01-08T16:33:55.124800Z

@d.ian.b dependency injection in Pathom is accomplished by env, you can add things to env at call time (when calling the parser), or in any point you want, so you can pull those in any part of the system, makes sense?

1šŸ¦œ
wilkerlucio 2021-01-08T16:35:18.124900Z

ok, foreign is still a very exploratory area, but I would try to avoid going too deep on this idea, since from the Pathom perpective that is hard to happen, one way to think of it is that params are always a "local" thing, while inputs are things that flow across

imre 2021-01-08T16:35:19.125100Z

The concept of parameters is interesting in that it's orthogonal to outputs. However, if they cannot be built on with other resolvers, that could make it risky to depend on them

wilkerlucio 2021-01-08T16:35:46.125300Z

one acceptable thing is for a resolver to accept some data as input OR params, this way you can have both options

wilkerlucio 2021-01-08T16:36:15.125500Z

the just released optional inputs on Pathom 3 can help with that, so you can have soft dependencies on specific attributes

wilkerlucio 2021-01-08T16:37:06.125700Z

but about foreign, its still experimental area, more work on it will come in Pathom 3, and feedback is very appreciated, if you have some cases you like to share, I'll love to hear about them

wilkerlucio 2021-01-08T16:38:48.125900Z

another alternative to sideways communication is to have some mutable state in the env, you can add a new atom there, modify from one resolver and read in the other, this is a tricky option and I suggest a lot of care if you try this path, but its there

2021-01-08T17:00:38.127300Z

Hey @wilkerlucio I kinda did some cursory poking around and couldnā€™t find anything analogous to async parsing in pathom2 so that I can use core.async with pathom3. Any pointers?

wilkerlucio 2021-01-08T17:01:03.127400Z

its on the backlog, but not available in Pathom 3 yet

wilkerlucio 2021-01-08T17:01:32.127600Z

but I hope an initial version of it should land in the next few weeks

3šŸ‘
2021-01-08T17:03:22.128Z

I will try doing some comparison between Integrant / Pathom then šŸ˜„

2021-01-08T17:25:00.128500Z

imo dependency injection is quite easy in Clojure because of immutable data structure. You can use Pathom, Prismatic Plumbing, Integrant or even Datascript. The (harder) related problem is starting/stopping components and that's what Integrant (and Duct) does

2021-01-08T17:26:45.128700Z

why not start / stopping components via pathom?

imre 2021-01-08T17:38:52.129100Z

Thank you for the insight. Fortunately in this case the foreign service is under control so we can change it. Will be a bit of extra work but I certainly wouldn't want to use the lib in a non-intended way. I'm sure we'll get back to you wrt foreign resolvers šŸ˜‰

wilkerlucio 2021-01-08T17:58:07.129300Z

you can, and for that I suggest you can use the https://pathom3.wsscode.com/docs/cache#custom-cache-store-per-resolver to share a cache on the resolvers that are for building up initialization

wilkerlucio 2021-01-08T17:58:24.129600Z

this way you can make them persistent, at the same time they will delay initialization until something in the system needs them

1šŸ¦œ
wilkerlucio 2021-01-08T17:59:01.129800Z

@d.ian.b if you want I can review the code with you once you have it

wilkerlucio 2021-01-08T17:59:32.130Z

altough, there is no stop šŸ˜›

2021-01-08T18:00:56.130200Z

and if I want to use pathom2 for this?

wilkerlucio 2021-01-08T18:01:53.130500Z

again, altough you can, I think something like "component" still a better option, because on Pathom you can't stop in reverse order, so not as good to this kind of initialization

1
wilkerlucio 2021-01-08T18:43:08.131Z

will be merged soon

wilkerlucio 2021-01-08T18:43:40.131200Z

(in this value2 is always tried first, default priority is 0, higher numbers go first)

2021-01-08T20:01:20.132900Z

Does anyone know where an example is in the documentation (or anywhere, really) about how to construct a query for a resolver with two items in ::pc/input?

2021-01-08T20:01:45.133300Z

e.g. ::pc/input #{:item-1 :item-2}

2021-01-08T20:18:11.134Z

https://blog.wsscode.com/pathom/#_multiple_inputs indicates that it can be done, as the ā€œinput to a resolver is a setā€, but I canā€™t find any examples anywhere.

wilkerlucio 2021-01-08T20:19:57.134400Z

@kendall.buchanan the example you sent is correct, are you having troubles to make it work?

2021-01-08T20:22:32.134800Z

I just donā€™t know what a query looks like that resolves to that resolver.

2021-01-08T20:23:20.135700Z

[{[[:item-1 "hello"] [:item-2 "world"]] [:what-im-fetching]}]

2021-01-08T20:23:28.136Z

This doesnā€™t appear to work.

2021-01-08T20:25:25.137300Z

The best I can come up with is to combine them into a single ::pc/input #{:item-1+2} with a query like [{[:item-1+2 {:item-1 "hello" :item-2 "world"] [:what-im-fetching]}]

2021-01-08T20:28:53.138800Z

Good to hear from you @wilkerlucio, by the wayā€”we had dinner together a couple years ago at Clojure/conj šŸ‘‹. One of our devs has jumped all in with Pathom; Iā€™m just getting my feet wet.

wilkerlucio 2021-01-08T20:34:34.139100Z

@kendall.buchanan you can find an example here: https://blog.wsscode.com/pathom/v2/pathom/2.2.0/connect/resolvers.html#_multiple_inputs

wilkerlucio 2021-01-08T20:34:56.139600Z

but other than a query itself, you could start from one data point, then a resolver realizes those 2 attributes, which then calls the next one

wilkerlucio 2021-01-08T20:35:31.139800Z

glad to hear about you too, great times at Conj, can't wait for us to be able to do another one of those again šŸ™‚

2021-01-08T21:06:08.142100Z

Okay, Iā€™m wondering if Iā€™m genuinely not understandingā€¦

2021-01-08T21:06:27.143Z

`[{([:customer/id 123] {:pathom/context {:customer/first-name ā€œFooā€ :customer/last-name ā€œBarā€}}) [:customer/full-name]}]`

wilkerlucio 2021-01-08T21:06:33.143300Z

hello everyone, another feature out šŸŽ‰! Now you can express different priorities for resolvers, so in cases that pathom need to choose, you can have a say on it: https://pathom3.wsscode.com/docs/resolvers#prioritization

1šŸ‘3šŸ™2šŸŽ‰
wilkerlucio 2021-01-08T21:06:52.143600Z

lets go by steps šŸ™‚

wilkerlucio 2021-01-08T21:07:24.143800Z

the [:customer/id 123] will set the :customer/id value, and the :pathom-context (when sent as a param to the ident) merges that data in as well

2021-01-08T21:07:48.144Z

::pc/input #{:customer/id :customer/first-name :customer/last-name}

wilkerlucio 2021-01-08T21:08:05.144200Z

you probably don't need those 3, you could use any ident there

wilkerlucio 2021-01-08T21:08:21.144400Z

Pathom is about "shape matching", so imagine that if you have enough to trigger a resolver, pathom will do it

2021-01-08T21:08:30.144600Z

Sureā€¦

2021-01-08T21:08:42.144800Z

But some data requires more than one input.

2021-01-08T21:09:07.145Z

Hereā€™s a more concrete exampleā€¦

2021-01-08T21:09:27.145200Z

I have a user with multiple logins across multiple apps.

2021-01-08T21:09:37.145400Z

Trying to fetch a record of the most recent login.

2021-01-08T21:10:02.145600Z

I can build a chain of resolvers that will eventually get me that information, from a single user IDā€¦

2021-01-08T21:10:27.145800Z

But that inevitably passes through many more layers than is necessary.

2021-01-08T21:10:37.146Z

Assuming I can pass a user ID, and an app ID.

2021-01-08T21:10:49.146200Z

(This is not my exact situation, but it simplifies it.)

wilkerlucio 2021-01-08T21:12:00.146400Z

here is a full example:

wilkerlucio 2021-01-08T21:12:02.146600Z

(ns com.wsscode.demos.multiple-inputs
  (:require [com.wsscode.pathom.core :as p]
            [com.wsscode.pathom.connect :as pc]))

(def users-db
  {1 {:user/first-name "Sam"
      :user/last-name  "Rock"}})

(pc/defresolver user-by-id [env {:keys [user/id]}]
  {::pc/input  #{:user/id}
   ::pc/output [:user/first-name :user/last-name]}
  (get users-db id))

(pc/defresolver full-name [env {:user/keys [first-name last-name]}]
  {::pc/input  #{:user/first-name :user/last-name}
   ::pc/output [:user/full-name]}
  {:user/full-name (str first-name " " last-name)})

(def registry
  [user-by-id full-name])

(def parser
  (p/parser
    {::p/env     {::p/reader               [p/map-reader
                                            pc/reader2
                                            pc/open-ident-reader
                                            p/env-placeholder-reader]
                  ::p/placeholder-prefixes #{">"}}
     ::p/mutate  pc/mutate
     ::p/plugins [(pc/connect-plugin {::pc/register registry})
                  p/error-handler-plugin
                  p/trace-plugin]}))

(comment
  ; just use the ident, pull name from resolver
  (parser {} '[{[:user/id 1] [:user/full-name]}])

  ; provide data, note we use an id that dont even exist
  (parser {} '[{([:user/id 3] {:pathom/context {:user/first-name "Foo" :user/last-name "Bar"}})
                [:user/full-name]}])

  ; to show the ident doesn't matter, changing it for anything else
  (parser {} '[{([:whatever-we-want "bla"] {:pathom/context {:user/first-name "Foo" :user/last-name "Bar"}})
                [:user/full-name]}]))

wilkerlucio 2021-01-08T21:12:50.146800Z

the :user/full-name does what you said, depending on multiple attributes, and getting then from the fake db load

2021-01-08T21:14:11.147Z

But what if this person has multiple names he goes by. You know what I mean?

2021-01-08T21:14:23.147200Z

In this example, the first and last name are derived automatically.

wilkerlucio 2021-01-08T21:16:39.147400Z

not sure if I get what you mean

wilkerlucio 2021-01-08T21:16:44.147600Z

what you mean multiple names?

2021-01-08T21:17:47.147800Z

(def users-db
  {1 {:public-name {:user/first-name "Sam"
                    :user/last-name  "Rock"}
      :secret-name {:user/first-name "Ram"
                    :user/last-name  "Sock"}}})

wilkerlucio 2021-01-08T21:18:11.148Z

in the core its about attribute relations, and how one attribute relates to another, so in this case we are expressing what a full name means

wilkerlucio 2021-01-08T21:18:37.148200Z

that example you just sent is a different thing

2021-01-08T21:18:56.148400Z

Thatā€™s what Iā€™m trying to get at: how do I get to my data assuming there is no derivation for the second piece of data.

wilkerlucio 2021-01-08T21:19:08.148600Z

its not just multiple inputs, but nested inputs, when you need to depend on some deeper shape, you would have to make a decision of which to pick in the end somehow

2021-01-08T21:19:11.148800Z

That the query is fundamentally incomplete without two data points.

wilkerlucio 2021-01-08T21:19:34.149Z

I woulnd't say incomplete, it just depends on your system

wilkerlucio 2021-01-08T21:19:48.149200Z

that example I show on full name is a common one, and in most systems the user will only have one field for it

wilkerlucio 2021-01-08T21:20:03.149400Z

then its about modeling the semantics of your system

wilkerlucio 2021-01-08T21:20:18.149600Z

the nested thing you sent is possible in Pathom 3: https://pathom3.wsscode.com/docs/resolvers#nested-inputs

wilkerlucio 2021-01-08T21:20:50.149900Z

but I feel like this is not what you thinking about, I fell like you have some misconception we didn't figure here yet

2021-01-08T21:21:05.150100Z

I see where youā€™re going about nested resolversā€¦

2021-01-08T21:21:09.150300Z

Or subqueries, I suppose.

2021-01-08T21:21:21.150500Z

But, why is a subquery necessary if I already have my data?

2021-01-08T21:21:40.150700Z

If I know X and Y, why can I not write a resolver that reacts to the existence of X and Y?

wilkerlucio 2021-01-08T21:21:41.150900Z

sometimes you dont

wilkerlucio 2021-01-08T21:21:46.151100Z

as the aggrgation example I show in the docs

wilkerlucio 2021-01-08T21:21:54.151300Z

you can

wilkerlucio 2021-01-08T21:21:57.151500Z

I still dont understand what you are trying to do

2021-01-08T21:22:09.151800Z

Take the example you posted hereā€¦

wilkerlucio 2021-01-08T21:22:12.152Z

what is the shape you have? what do you want in the end?

2021-01-08T21:22:30.152200Z

Assume Iā€™m looking up a name, based on an ID.

2021-01-08T21:22:41.152400Z

(Not caring for :customer/full-name, just looking up a name.)

wilkerlucio 2021-01-08T21:22:46.152600Z

ok

2021-01-08T21:22:47.152800Z

But the user has multiple names, of different types.

wilkerlucio 2021-01-08T21:22:58.153Z

lets give names, you want :user/name, you have :user/id

2021-01-08T21:23:08.153200Z

Noā€¦ not quiteā€¦

wilkerlucio 2021-01-08T21:23:15.153400Z

what you mean multiple names? are from multiple sources?

wilkerlucio 2021-01-08T21:23:31.153600Z

can you give an example?

2021-01-08T21:23:39.153800Z

Yeah, lemme write out some dataā€¦

wilkerlucio 2021-01-08T21:25:07.154Z

its helps to think about the output shape you want, so we can build the chain from it, and in the end you have to give names to every attribute you want to return, thinking like that often helps me figure it out

2021-01-08T21:25:12.154200Z

You know what, I think youā€™re right: itā€™s about the semantics of the keys.

2021-01-08T21:25:22.154400Z

Rightā€¦

2021-01-08T21:25:52.154600Z

Iā€™m imagining my resolver working with this:

2021-01-08T21:25:54.154800Z

(def users-db
  {1 {:public-name {:user/first-name "Sam"
                    :user/last-name  "Rock"}
      :secret-name {:user/first-name "Ram"
                    :user/last-name  "Sock"}}})

2021-01-08T21:26:01.155Z

When, I think what youā€™re saying isā€¦

2021-01-08T21:26:25.155200Z

(def users-db
  {1 {:user.public/first-name "Sam"
      :user.secret/first-name "Ram"}})

wilkerlucio 2021-01-08T21:26:30.155400Z

yup

2021-01-08T21:26:38.155600Z

In other wordsā€¦

wilkerlucio 2021-01-08T21:26:42.155800Z

in Pathom its good to keep things as flat as possible

2021-01-08T21:26:46.156Z

It pushes the burden of shaping the data further down into the system.

wilkerlucio 2021-01-08T21:26:51.156200Z

gives more leverage

2021-01-08T21:26:52.156400Z

(In my real world example.)

2021-01-08T21:27:39.156600Z

But how would that work when user.x is unknown/

2021-01-08T21:27:40.156800Z

?

2021-01-08T21:27:48.157Z

:user.x/first-name

2021-01-08T21:28:10.157200Z

Or infinite options.

wilkerlucio 2021-01-08T21:28:18.157400Z

you can't do that, Pathom must know about the attributes of the system, infinite attributes is not a thing

2021-01-08T21:28:18.157600Z

Iā€™ll have to think on that.

wilkerlucio 2021-01-08T21:28:30.157800Z

because Pathom is based on index processing, it has to know ahead of time about all relationships

wilkerlucio 2021-01-08T21:28:56.158Z

I'm curious where you land, IME this has never been a limitation so far, maybe you find one, hehe

2021-01-08T21:29:35.158300Z

The situation I have is thisā€¦

2021-01-08T21:29:46.158500Z

We have an infinite number of users (with ids)ā€¦

2021-01-08T21:29:59.158700Z

And they play ā€œgamesā€, I suppose you could call them.

2021-01-08T21:30:05.158900Z

And the number of games they play is infinite.

2021-01-08T21:30:18.159100Z

But the number of times they play the game is also infinite.

2021-01-08T21:30:33.159300Z

So, Iā€™m trying to fetch a record of their most recent session, given a user ID, and a game ID.

2021-01-08T21:30:49.159500Z

Simple SQL query.

2021-01-08T21:30:54.159700Z

WHERE clause takes two params.

2021-01-08T21:31:04.159900Z

But I canā€™t understand how this translates to Pathom.

2021-01-08T21:31:37.160100Z

Takes two joins in SQL across three tables. Itā€™s a junction, essentially.

2021-01-08T21:31:57.160300Z

And I donā€™t see how Pathom handles a junctionā€”where two indexes are required to resolve it.

2021-01-08T21:32:18.160500Z

(Thank you for all this attention, by the wayā€”surely you have important things to be doing.)

wilkerlucio 2021-01-08T21:32:36.160700Z

it really helps if you start naming the attributes that participates in this query, I dont see any unbounded attributes in what you said, from the messages I can extract: :user/id :game/id, :session/id (maybe), I mean, Pathom is a connector, you can make the resolver do anything

wilkerlucio 2021-01-08T21:32:43.160900Z

what you described looks like a resolver with a query

wilkerlucio 2021-01-08T21:32:54.161100Z

the session is another table?

2021-01-08T21:33:16.161300Z

The ā€œclientā€ has the :user/id and :game/id, and is seeking a :session/id.

wilkerlucio 2021-01-08T21:33:17.161500Z

what you want to get select * from game_session where userid = 10 AND gameid= 20, like this?

wilkerlucio 2021-01-08T21:33:38.161700Z

and then, from the session, what data you expect out (name in attributes)

2021-01-08T21:33:38.161900Z

Yeah, more or less.

wilkerlucio 2021-01-08T21:33:39.162100Z

?

2021-01-08T21:33:54.162300Z

:session/id.

2021-01-08T21:33:58.162500Z

That is whatā€™s needed.

wilkerlucio 2021-01-08T21:35:09.162700Z

(pc/defresolver user-session [env {user-id :user/id game-id :game/id}]
  {::pc/input  #{:user/id :game/id}
   ::pc/output [:session/id]}
  (let [res (fake-sql (str "select session_id from sessions where user_id=" user-id " and game_id = " game-id))]
    {:session/id (:session_id res)}))

wilkerlucio 2021-01-08T21:35:16.162900Z

something like this

wilkerlucio 2021-01-08T21:35:46.163100Z

you probably want a different resolver to generate those combinations

wilkerlucio 2021-01-08T21:35:49.163300Z

something like:

2021-01-08T21:36:07.163500Z

Yeah. My original question was how to construct the EQL for that: ::pc/input #{:user/id :game/id}

wilkerlucio 2021-01-08T21:37:11.163700Z

(pc/defresolver games-from-user [env {:keys [user/id]}]
  {::pc/input  #{:user/id}
   ::pc/output [{:user/games [:user/id :game/id]}]}
  ; assume this returns a list of game ids
  (let [res (find-games-from-user env id)]
    {:user/games (mapv #(hash-map :user/id id :game/id %) res)}))

wilkerlucio 2021-01-08T21:37:28.163900Z

now you can run: [{[:user/id 1] [{:user/games [:session/id]}]}]

wilkerlucio 2021-01-08T21:38:23.164100Z

its really up to you to model, its just different, and takes some practice to adjust

2021-01-08T21:38:34.164300Z

Yeah. IMO, this is constraint that I donā€™t understand.

2021-01-08T21:38:50.164500Z

Two constraints it imposesā€¦

2021-01-08T21:39:01.164700Z

Prevents the resolver writer from tailoring more performant resolvers.

wilkerlucio 2021-01-08T21:39:22.164900Z

I suggest you take a read on this page: https://pathom3.wsscode.com/docs/planner

2021-01-08T21:39:27.165200Z

And limits the type granularity of responses for the client.

wilkerlucio 2021-01-08T21:39:59.165400Z

this explains how pathom 3 plans for the graph, pathom 2 is bit different, but the main idea is the same, when it sees something the user wants, it traverses the indexes for that attribute, to figure how to reach it

2021-01-08T21:40:00.165600Z

But if I have a SQL query that can fetch one item faster than N, your example suggests it canā€™t be used.

wilkerlucio 2021-01-08T21:40:23.165800Z

you can create as many paths as you want, so you can make a direct one if you want to

wilkerlucio 2021-01-08T21:40:34.166Z

and we are limiting our chat here around "static resolvers"

wilkerlucio 2021-01-08T21:41:22.166200Z

to get as efficient as what you saying, there are the dynamic resolvers (still getting mature), but their ability is to have dynamic inputs and outputs, that responds depending on the user requirement (and dependencies requirements)

wilkerlucio 2021-01-08T21:41:39.166400Z

this is done to call GraphQL for example, where it would be very inneficient if each attribute made its own call

2021-01-08T21:41:41.166600Z

In other wordsā€¦

2021-01-08T21:41:46.166800Z

::pc/input #{:user/id :game/id}

wilkerlucio 2021-01-08T21:41:51.167Z

so the dynamic resolvers have a different thing, they can optimize laterally

2021-01-08T21:41:58.167200Z

There is no way to satisfy this, correct?

wilkerlucio 2021-01-08T21:42:11.167400Z

what you mean you can't satisfy?

2021-01-08T21:42:17.167600Z

In a single trip to the resolver index.

wilkerlucio 2021-01-08T21:42:19.167800Z

you can provide the data for it, or provide resolvers to reach it

2021-01-08T21:42:30.168Z

you can provide the data for it

wilkerlucio 2021-01-08T21:42:34.168200Z

have you seen what the indexes look like?

2021-01-08T21:42:36.168400Z

What does the query look like?

wilkerlucio 2021-01-08T21:43:00.168600Z

I sent you at the two final examples:

(comment
  ; just use the ident, pull name from resolver
  (parser {} '[{[:user/id 1] [:user/full-name]}])

  ; provide data, note we use an id that dont even exist
  (parser {} '[{([:user/id 3] {:pathom/context {:user/first-name "Foo" :user/last-name "Bar"}})
                [:user/full-name]}])

  ; to show the ident doesn't matter, changing it for anything else
  (parser {} '[{([:whatever-we-want "bla"] {:pathom/context {:user/first-name "Foo" :user/last-name "Bar"}})
                [:user/full-name]}]))

wilkerlucio 2021-01-08T21:43:06.168800Z

using :pathom/context param is a way

wilkerlucio 2021-01-08T21:43:23.169Z

you can also provide though the env, setting ::p/entity (atom {:data "here"}

2021-01-08T21:43:35.169200Z

And either key can be in the tuple?

wilkerlucio 2021-01-08T21:43:59.169500Z

yeah, the key there doesn't matter

wilkerlucio 2021-01-08T21:44:25.169700Z

this is more a legacy from Fulcro integration, in this case (for Fulcro) the ident part can tell which local table it should use, without matter what the rest of the context is

wilkerlucio 2021-01-08T21:44:33.169900Z

this an example providing data via env:

wilkerlucio 2021-01-08T21:44:35.170100Z

(parser {::p/entity (atom {:user/first-name "Foo" :user/last-name "Bar"})}
    '[:user/full-name])

2021-01-08T21:44:39.170400Z

([:user/id 3] {:pathom/context {:game/id 1}}]) is the same as ([:game/id 1] {:pathom/context {:user/id 3}}])

wilkerlucio 2021-01-08T21:44:48.170600Z

yeah

2021-01-08T21:44:57.170800Z

Okay. Iā€™m assuming that was never desirable, right?

wilkerlucio 2021-01-08T21:45:01.171Z

it only shapes your output shape (which will match the ident)

2021-01-08T21:45:02.171200Z

Justā€¦ legacy, like you say.

wilkerlucio 2021-01-08T21:45:18.171400Z

its was a later addition to support extra inputs at query level

2021-01-08T21:45:53.171700Z

K, Iā€™ll give all your feedback some thought for how I construct our actual resolvers. Thank you again. Big help. Love the project.

1šŸ™
2021-01-08T21:46:12.171900Z

If I had any feedback, it seems to me that multiple params in the queries ought to be natively supported, but perhaps I just have more adjusting to do.

wilkerlucio 2021-01-08T21:46:44.172200Z

in Pathom 3 you can use placeholders for a simpler version of it

2021-01-08T21:47:02.172400Z

You feel like itā€™s ready for real use?

wilkerlucio 2021-01-08T21:47:33.172600Z

not yet, but its quite easy to implement that feature in Pathom 2, I think I'll do that today, because you are not the first person asking, hehe

2021-01-08T21:47:45.172800Z

Oh good, hehe. Thank you !

wilkerlucio 2021-01-08T21:48:08.173Z

you can see what it looks like here: https://pathom3.wsscode.com/docs/placeholders#provide-data

wilkerlucio 2021-01-08T21:49:48.173300Z

Pathom 3 is getting there, I think its good for experiments and small usages, but its lacking tooling, so when things start to get complicated, the tooling can be quite missed

wilkerlucio 2021-01-08T21:50:18.173500Z

but in terms of core features, it has a lot done already

Lucas Senna 2021-01-08T23:24:44.173900Z

Bumping org.clojure/core.async to the latest stable version did the trick. Thanks a lot, man.