pathom

:pathom: https://github.com/wilkerlucio/pathom/ & https://pathom3.wsscode.com & https://roamresearch.com/#/app/wsscode
2020-10-20T13:11:41.133800Z

Hey, could anyone point me to an example on how to wrap a rest api in pathom for a Fulcro app?

souenzzo 2020-10-20T13:33:36.134Z

- Create a transmit! function to "adapt" pathom into "remote" interface https://github.com/souenzzo/eql-realworld-example-app/blob/master/src/conduit/client/rest.cljs#L17

souenzzo 2020-10-20T13:34:13.134300Z

- Create a parser with the resolvers from your rest API https://github.com/souenzzo/eql-realworld-example-app/blob/master/src/conduit/client/rest.cljs#L32

2020-10-20T13:54:04.134900Z

thank you! im doing the flux challenge just to wrap my head around fulcro pathom and really hit a road block because most of the examples assume you want graphql or are talking to a db

2020-10-20T13:56:43.135100Z

https://github.com/staltz/flux-challenge

2020-10-20T14:27:36.135400Z

@souenzzo do you have a blog or anything where you write about things? Iā€™d subscribe šŸ‘€

2020-10-20T15:02:37.135600Z

i have another example hitting the wikipedia api: https://github.com/dvingo/pathom-client-wikipedia/blob/master/src/main/dv/pathom_wp/client/application.cljs#L18 hosted on github pages: https://dvingo.github.io/pathom-client-wikipedia/

šŸ‘ 1
yenda 2020-10-20T15:56:23.137700Z

Currently pathom returns only one result for the same mutation, for instance if the user has a connection issue and the query grows into calling the same mutation with different params twice, I only get the result of the last one. Is there a way to have both or could it be included in a future version?

wilkerlucio 2020-10-21T12:51:32.146200Z

hello, for your case @tekacs, you can go around this limitation by writing a mutation that sends multiple messages at once

wilkerlucio 2020-10-21T12:51:47.146400Z

or, some sort of mutation that composes other mutaitons

yenda 2020-10-21T14:54:32.146900Z

@wilkerlucio I merge queries into one until it can be sent, on retry it does one single query with all the pending ones

šŸ‘ 1
2020-10-21T17:21:59.147200Z

right, what yenda said @wilkerlucio

2020-10-21T17:22:13.147400Z

merging them into one doesn't really help, because it'd break ordering for one thing

2020-10-21T17:22:22.147600Z

[(mutation-1)
 (mutation-2)
 (mutation-1)]

2020-10-21T17:22:51.148Z

the only real option as far as I can tell is to manually split the mutations externally to Pathom and then to send them into the engine one at a time šŸ˜ž

2020-10-21T17:28:32.148700Z

I guess I could write a mutation that composes other mutations...

2020-10-21T17:29:09.148900Z

but would be wonderful if there were an ad-hoc way of simply giving each mutation its output name

yenda 2020-10-21T17:44:01.149100Z

which is why I was wondering if it could return a collection of results when the mutation was called more than once

yenda 2020-10-21T17:45:52.149300Z

if I'm not mistaken that would not even break existing queries, since for instance

(defn block-user
  [user-id blocked?]
  {(list 'block-user {:user/id user-id
                      :user/blocked? blocked?})
   [:user/id
    :user/blocked?]})
could anyway receive either one map or a coll of map

2020-10-21T18:01:05.149500Z

if we could rename outputs, then we could get the same effect as a collection by transforming queries to/from a form with renames

2020-10-21T18:01:10.149700Z

that's why that'd be my aim

2020-10-21T18:01:21.149900Z

I might see if I can do that in a plugin

yenda 2020-10-21T18:04:43.150100Z

If I'm not mistaken the overwrite occurs in mutate and mutate-async when the result is merged in the env

yenda 2020-10-21T18:16:48.150300Z

mhm actually looks like it's in the parser

yenda 2020-10-21T18:17:09.150500Z

(recur (assoc res (ast->out-key ast) value) tail)

yenda 2020-10-21T18:21:50.150700Z

would it be acceptable to do

(let [out-key (ast->out-key ast)
      previous-res? (get res out-key)]
  (recur (if previous-res?
           (update res out-key (fn [previous-res]
                                 (if (vector? previous-res)
                                   (conj previous-res res)
                                   [previous-res value])))
           (assoc res out-key value)) tail))

wilkerlucio 2020-10-21T18:44:00.150900Z

@yenda the vector thing is a problem, because it breaks the assumption that mutations always return a map, I think a behavior like that could be confusing. there is a plugin entry point that I've been considering for a while, and I think it could solve this problem, is a ::p/wrap-output, something to run exactly when pathom is building the output, with this hook you could either write a plugin to use some param and have some different output name (like alias works for reads today) or even make what you are suggesting. this was planned for Pathom 3, but I can make in Pathom 2, this can also give some room to experiment with this entry point

yenda 2020-10-21T18:53:59.151100Z

yeah the plugin way would be satisfying enough, I had the assumption mutations would return a vector when ran more than once like resolvers when they return more than one result šŸ˜„

yenda 2020-10-20T18:30:01.142200Z

It could return a vector of results in the mutation key?

wilkerlucio 2020-10-20T20:36:20.143800Z

what you mean by query grows into calling same mutation with different params? in case of a retry isnt it a different request?

2020-10-20T23:16:23.144700Z

@wilkerlucio I think I came here to ask this exact question myself, too šŸ˜†

[(send-message {:message/text "hey"})
 (send-message {:message/text "there"})]

#_=>

{send-message {:message/sent "there"}}
that's just an example, but the gist is that with mutations sitting at the root (and you can't AFAICT join them under placeholder prefixes either), if you send a query that uses (send-message ...) twice, there's not an obvious way to capture the return values from both of those mutations, since they both write into {send-message ...} at the top level. Does that make it clearer?

2020-10-20T23:17:37.144900Z

I would do this or something similar if I could:

[{:>/first (send-message ...)}
 {:>/second (send-message ...)}]
but that comes out as an invalid join or maybe something like this, possibly?
[{(send-message ...) {:>/first [:message/sent]}}
 {(send-message ...) {:>/second [:message/sent]}}]
but that just yields an empty result map, like this:
{send-message {}}