Fork me on GitHub
#pathom
<
2023-01-20
>
Jakub Holý (HolyJak)00:01:55

Q1: Why might I be getting pathom3.connect.runner/event-batch-unsupported on a resolver that I believe has ::pco/batch? true ? The problem seems to have been with a resolver returning LazySeq as the value of one attribute; turning map to mapv fixed it. Q2: Why am I getting Batch results must be a sequence and have the same length as the inputs. when my resolver gets a seq of maps as its input and returns [] (b/c there were no matches)? Am I supposed to return nil for each input w/o a match? If I do then then I get instead “Required attribute missing” (b/c nil lacks the declared pco/output) Reading the source of com.wsscode.misc.coll/restore-order it seems that indeed returning {<declared output> nil} for each item is the right way

Andy Carlile00:01:43

im a noob to pathom, om, and graphql. i'm losing my noodle over querying by id: https://clojurians.slack.com/archives/C053AK3F9/p1674170178447079

Jakub Holý (HolyJak)01:01:09

Another P3 mystery with a join. This returns as expected:

(parser {} [{[::person/id "ann"] [::person/addresses]} ])
; =>
{[::person/id "ann"] {::person/addresses [{::address/street "First St."}
                                          {::address/street "Second St."}]}}
but if I change it to specify I only want .../street for each address:
(parser {} [{[::person/id "ann"] [{::person/addresses [::address/street]}]} ])
; =>
{[::person/id "ann"] #::person{:addresses [{} {}]}}
no data is in the addresses 🤯 There is a single person-id resolver involved and it returns all the data needed, like this:
[#::person{:id "ann", :addresses [#::address{:id "a-one", :street "First St."} #::address{:id "a-two", :street "Second St."}]}]

wilkerlucio02:01:51

hello, that's seems off, but maybe its something with idents, can you make a repro please?

👍 2
Jakub Holý (HolyJak)21:01:32

Hi Wilker! I found out that of course the problem was with my resolver, I just did not see it 😅

Jakub Holý (HolyJak)00:01:52

@U066U8JQJ I have figured out 4 ways to fix my code ☝️ to return the expected data but still do not understand why the version I have is “broken” and returns [{} {}] instead of the addresses. The thing is that I have 2 resolvers: 1) a person resolver that returns the whole data, 2) an address resolver for :address/id -> :address/street. The 4 ways to fix the resolution to return the expected street names are: 1. Change the person/id resolver’s outputs to declare [ .. :person/addresses ..] instead of [.. #:person{:addresses [:address/id]} ..] 2. Change the person/id resolver’s outputs to also include address/street, i.e. [.. #:person{:addresses [:address/id :address/street]} ..] 3. Remove the resolver for address/id → address/street 4. Change the person/id resolver to only return address/id and not the street Here is the simplest possible code to demonstrate the issue (in its “broken” state):

(def asami-p3-pers-resolver-diy
  (pco/resolver
    {::pco/op-name 'asami-p3-pers-resolver-diy
     ::pco/batch?  true
     ::pco/input   [:person/id]
     ::pco/output  [; fix 1: use just `:person/addresses` inst. of the join below
                    #:person{:addresses [:address/id ; fix 2: add `:address/street` here
     ]}]
     ::pco/resolve (fn [_env in]
                     (println "JHDBG: asami-p3-pers-resolver-diy" in)
                     [#:person{:id "ann", :addresses [#:address{:id "a-one", :street "First St."}
                                                      #:address{:id "a-two", :street "Second St."}]}])}))

(def asami-p3-addr-resolver-diy
  (pco/resolver
    {::pco/op-name 'asami-p3-addr-resolver-diy
     ::pco/batch?  true
     ::pco/input   [:address/id]
     ::pco/output  [:address/street]
     ::pco/resolve (fn [_env in]
                     (println "JHDBG: asami-p3-addr-resolver-diy" in) ; never called!
                     [#:address{:id "a-one", :street "First St."}
                      #:address{:id "a-two", :street "Second St."}])}))

(p.eql/process
  (pci/register [asami-p3-pers-resolver-diy 
                 ; fix 3: comment out the resolver below:
                 asami-p3-addr-resolver-diy])
  [{[:person/id "ann"] [{:person/addresses [:address/street]}]}])
What I do not understand why the presence of the address resolver makes the data disappear, even though the resolver is never called. Thank you very much for any insights! PS: My whole laborious exploration is recorded in https://gist.github.com/holyjak/9951076cbaaac945be43cec98e2e41b0#troubleshooting-auto-generated-fulcro-rad-id-resolvers-in-pathom-3

Jakub Holý (HolyJak)15:01:58

@U066U8JQJ sorry to bother you but do you think ☝️ is a bug and should I create an issue for it?

wilkerlucio13:01:54

hello @U0522TWDA, sorry the delay, I plan to have a proper read and get back to you later today

🙏 2
Jakub Holý (HolyJak)13:01:43

You don’t need to read the whole thread, just the last message with code 🙂 thank you!

wilkerlucio21:01:39

hello, just took the time to run your code, I have one more fix 😛 there is, remove ::pco/batch? from asami-p3-pers-resolver-diy, which makes me think its same issue reported in #173 and #177, also this discussion here: https://clojurians.slack.com/archives/C87NB2CFN/p1674636918359429

wilkerlucio21:01:43

and thanks for the extra repro, good that I will by able to validate the solution in a few different examples

wilkerlucio21:01:42

altough, for your case, the fix 1 is the correct way to do it, since the street is available at the output data

wilkerlucio21:01:16

but it still a Pathom issue on how its handling it without, it should be able to figure out (although less optimal, given it could avoid some things if it knew the exact nested shape)

wilkerlucio21:01:50

just found something that might make your case different

wilkerlucio21:01:18

(p.eql/process
    (pci/register [asami-p3-pers-resolver-diy
                   asami-p3-addr-resolver-diy])
    {:person/id "ann"}
    [{:person/addresses [:address/street]}])

wilkerlucio21:01:23

this works fine ☝️

wilkerlucio21:01:34

so there might be something with batch + idents that's off here

wilkerlucio21:01:29

@U3XCG2GBZ this observation also matches your report, this also works in your setup:

(p.eql/process env
    {:child/id 1}
    [{:child/favorite-toy [:toy/name]}])

Jakub Holý (HolyJak)09:01:16

The problem here is that these resolvers are auto-generated. And they may sometimes return more nested data, sometimes only the (declared) id. So changing the :outputs is not really an option. I have a workaround for now, just need to make sure the resolvers do not return anything extra. But it would be nice to be able to do that. FYI The problem popped-up in in https://github.com/holyjak/fulcro-rad-asami/blob/18729aaea22b37c2cbf2d00a08a62f87b1b37030/src/cz/holyjak/rad/database_adapters/asami/pathom_common.cljc#L110 plugin. It gets triggered when people insert data manually and incorrectly (i.e. sub-entities such as addresses as nested entities instead of top-level entities). Which should normally not happen if they use the plugin as designed. Thank you for looking into this!

wilkerlucio10:01:35

until there is a proper fix, one solution is to use the parallel runner, the parallel runner uses a different mechanism for batching and doesn't have this bug

wilkerlucio10:01:18

from your example, this works fine:

@(p.a.eql/process
     (pci/register
       {::p.a.eql/parallel? true}
       [asami-p3-pers-resolver-diy
        ; fix 3: comment out the resolver below:
        asami-p3-addr-resolver-diy])
     [{[:person/id "ann"] [{:person/addresses [:address/street]}]}])

Jakub Holý (HolyJak)11:01:19

Good to know, thank you!

Panel04:01:14

Would anyone have an example of using dynamic resolvers to batch requests to an external api ?

wilkerlucio13:01:53

hello Panel, can be a bit more specific? what kind of external api? is it a simple HTTP request? I'm wondering if you really want a dynamic resolver, or just a batch resolver

Panel22:01:09

I’m wrapping a xml-rpc api. You can describe the data you want with xml and get many different entities back in a single http call. So in pathom I could have a resolver per entity that make a http call each but I could also find a way to batch those http call because the xml-rpc endpoint allow to send many request at once.

wilkerlucio16:01:45

gotcha, in general the process here is to figure a out to translate the foreign schema in Pathom resolvers, can you instropect that API to get its description?

Panel21:01:58

Yes I know what entities I can fetch and the payload I need to get them. I made a resolver per entity and it works but it’s making a lot of extra request by not using the ability to fetch multiple entities per call. It’s like if I had a rest api where I could send it [/user/1/adresse /user/1/pets /user/1/keys] Instead of making 3 separate call. If dynamic resolvers is the way to go, I think need to figure out how to define the ast for my foreign api.

wilkerlucio13:01:20

the ast gets build by pathom for you to process via the dynamic resolver, in case of batches its the same, but you get multiple things, and have to figure how to send out/process back of them in one request

wilkerlucio23:01:41

if that's something you can share, I could look at how to make it with you

parameme11:01:00

In the last non command-line syntax block in the tutorial code above the concept or symbol woeid is only referenced twice in the registration in the env and doesn’t seem bound / defined. Am I missing something?

wilkerlucio13:01:37

ups, thanks for the pointer, removed the last reference of woeid that I found from the previous tutorial: https://github.com/wilkerlucio/pathom3-docs/commit/3dedbf24fcf4c0b5ed24ca5ab8f33df222a8a733

👏 2