Fork me on GitHub

I was inspired by @wilkerlucio response to someone asking about how to write Pathom queries, and attempted to write one myself. I found myself immediately wanting to implement it by composing: 1) get all the stories (a query I had already written [:story/all-stories], and then 2) filter them according to the given criteria. I’m delighted I got something working, but for expediency, did something quite ugly — I called parser from inside the resolver, using resolve to avoid the circular dependency, fetching parser/parser and parser/config ,which I had to deref to avoid Don't know how to create ISeq from: clojure.lang.Var error. It works, but I’m guessing there’s a better way to retrieve an EQL query? Or compose resolvers? Thx!


hello @genekim, for this would be better if you use :story/all-stories as the input in the story-search-resolver, this way you don't have to call the parser from inside


in Pathom 3 this story is better, because you can do nested inputs on Pathom 3, this means your resolver could have: ::pco/input [{:story/all-stories [:story/id :story/author :story/title]}]


this way, even if the query is complex (for the nested part under all-stories) Pathom would resolve it first and give the exact input requested


but if you need the nested details in Pathom 2, them doing a recursive call to the parser is the only way


Holy cow, @wilkerlucio — ::pco/input. That’s amazing. Reading docs on this right now. To confirm my understanding: this would make :story/all-stories available from inside the search resolver, and then I could filter on this?

👍 2

(pathom2, as I’m using Fulcro)


Trying to wrap my head around 1) how to get all the stories in the env. This is the current query that’s working, where search text comes in as a parameter.

['(:search-results/stories {:search/search-query "search text abc!"})])
to…. argh, can’t quite figure out where the :story/all-stories would go? I’m sure it’s not this…
[['(:search-results/stories {:search/search-query "search text abc!"})
Thx for your help here, @wilkerlucio!


here is a complete example:

(pc/defresolver all-items []
  {::pc/output [{:all-items [:id :name]}]}
   [{:id 1 :name "Aa"}
    {:id 2 :name "Ab"}
    {:id 3 :name "Bb"}
    {:id 4 :name "Cc"}]})

(pc/defresolver search [env {:keys [all-items]}]
  {::pc/input  #{:all-items}
   ::pc/output [{:search-results
                 [:id :name]}]}
  (let [search (-> env :ast :params :search)]
     (filterv #(str/starts-with? (:name %) search) all-items)}))

  (parser {} ['(:search-results {:search "A"})])
  (parser {} ['(:search-results {:search "B"})]))


(made in Pathom 2)


the second argument of the resolver is the input


@wilkerlucio Wow. That is so freaking cool. Absolutely freaking marvelous. THANK YOU!!


The more I study this, the more I feel like I understand Pathom, and the more I’m in awe of it. Freaking awesome, @wilkerlucio!


one way to look at is like pattern matching, but based on shapes of data (expressed in EQL)


It’s awesome — last question on this, before I call this done! Inspired by your response to that person in 2019, I want to put the search-text and the # of matches into the return result. Is this pc-output shape specified correctly?

(pc/defresolver story-search-resolver [env _]
       {; no ::pc/input
        ::pc/output [:search-results/search-text
                      [:story/id :story/title :story/author :story/content]}]}
         (log/warn "*** story-search-resolver")
         (handle-search env)))))
The return result from inside the resolver is shown in the screenshot, which looks good! It’s of the shape that I want/expect: But the actual return result from the resolver for this query is… confusing.
['(:search-results/stories {:search/search-query "re-frame"})
     [:search-results/matched :search-results/search-text
      {:search-results/stories [:story/author]}]])

; =>

{:search-results/stories (#:story{:id "K3Y7GLlRfaBDsUWYD0WuXjH/byGbQnwaMWp+PEBoUZw=_16f347d1381:18e306:512e2118",
                                  :author "Arne Brasseur",
                                  :title "Advent 2019 part 23, Full size SVG with Reagent",
                                  :content "XXXXXX"
 [:search-results/matched :search-results/search-text #:search-results{:stories [:story/author]}] #:search-results{:matched :search-results/search-text}}
1. I only wanted the story/author to be retrieved, but all the :story fields were retrieved. 2. The search-results/matched | search-text don’t show up as keys in the return map, but are nested inside a vector (or worse. 🙂 The shape I really want is:
#:search-results{:matched 0 :search-text "re-frame" :story #:story{:id :author :content :title}}
Thx again!


I just took a look, the issue is in you query I believe


you see. there is no connection in the query between :search-result/stories and the :search-result/matched ...


its missing a map connecting then


should be like this:

[{'(:search-results/stories {:search/search-query "re-frame"})
  [:search-results/matched :search-results/search-text
   {:search-results/stories [:story/author]}]}]


@wilkerlucio Holy cow. THANK YOU! (And a huge facepalm, seeing the missed join.). Can’t wait to see this run!