Fork me on GitHub
#pathom
<
2020-04-21
>
jeroenvandijk10:04:31

Hi, I’m exploring the features of Pathom. I’m wondering is there a builtin way to merge independent queries during one request. E.g. I would have an html page with independent blocks.

[:div
 [:div {:class "block 1"}
   (q [:album/name
       {:album/artist
        [:artist/name]}])]
 [:div {:class "block 2"}
   (q [:album/name
       {:album/tracks
        [:track/name]}])]]
Ideally, I would render this page after collecting all queries, and do only one query to the server:
[:album/name
 {:album/tracks
  [:track/name]
  :album/artist
  [:artist/name]}]
After receiving the result of the server it could be split into seperate results for the seperate queries. Does such an in-memory resolver already exist?

kszabo10:04:36

Yes, Fulcro does this automatically

jeroenvandijk10:04:02

Thanks, good to know. But is not part of Panthom? So I have to steal that there. (i’m not using Fulcro)

jeroenvandijk10:04:58

Maybe I’m looking for the Request cache (mentioned in the introduction). I’ll have a read

Request cache: For caching the results of parsing repetition that can happen on a single request.

kszabo10:04:47

those are separate ideas

kszabo10:04:06

you can easily merge separate EQL queries into one (if they do not have conflicts)

kszabo10:04:34

then that single EQL query resolution can be made more efficient inside Pathom using the request cache (and other techniques)

kszabo10:04:12

this is what you are looking for probably

jeroenvandijk10:04:17

I’ll do some reading and give this a try later

souenzzo13:04:33

@jeroenvandijk just "merge" your queries

(let [{:>/keys [a b]} (q [{:>/a [:album/name
                                 {:album/artist
                                  [:artist/name]}]}
                          {:>/b [:album/name
                                 {:album/tracks
                                  [:track/name]}]}])]
  [:div
   [:div {:class "block 1"}
    a]
   [:div {:class "block 2"}
    b]])

jeroenvandijk20:04:23

Thank you. I’ll give it a try

souenzzo14:04:07

Also you can use ::p/entity

(let [a (atom 0)
      register [(pc/resolver
                  `a 
                  {::pc/output [:a]}
                  (fn [_ _]
                    {:a (swap! a inc)}))]
      parser (p/parser {::p/plugins [(pc/connect-plugin {::pc/register register})]})
      env {::p/reader [p/map-reader
                       pc/reader2
                       pc/open-ident-reader
                       p/env-placeholder-reader]
           ::p/placeholder-prefixes #{">"}}
      ->cache (fn [parser]
                (let [entity (atom {})]
                  (fn [tx]
                    (parser (assoc env ::p/entity entity)
                            tx))))
      single-use-cached-parser (->cache parser)]
  [:without-cache [:div 
                   (parser env [:a])
                   (parser env [:a])]
   :with-cache [:div
                (single-use-cached-parser [:a])
                (single-use-cached-parser [:a])]])