Fork me on GitHub
#pathom
<
2023-06-03
>
kokonut19:06:02

Hi, I am a complete newbie that is learning Pathom. I am following the pathom3 documentation using my own example as follows.

(def person-db
  {1 {:person/person-id 1
      :person/first-name "Jack"
      :person/address-id 301}
   2 {:person/person-id 2
      :person/first-name "Daisy"
      :person/address-id 301}
   3 {:person/person-id 3
      :person/first-name "Bruce"
      :person/address-id 704}})
(def address-db
  {301 {:address/address-id 301
        :address/country :canada
        :address/province :nj
        :address/street "lucky street"}
   704 {:address/address-id 704
        :address/country :usa 
        :address/province :ca
        :address/street "love street"}})
I have been able to get most of queries work such as find address by person props. But how can I find all persons who live on "lucky screet"? The query would return two person objects for Jack and Daisy. I am not sure how though. Can someone enlighten me?

sheluchin20:06:52

@U022N1DU7GQ you would need to write a resolver that takes some parameters (like the name of the street) and does the work of filtering out the person-db to only return the records that match. https://pathom3.wsscode.com/docs/resolvers/#parameters

kokonut22:06:44

You are right @UPWHQK562. So I wrote

(pco/defresolver address-street->address-ids
  [{:address/keys [street]}]
  {::pco/output [:address/address-id]}
  (->> address-db
       vals
       (filter #(= street (:address/street %)))
       (map #(select-keys % [:address/address-id]))
       first))
(address-street->address-ids {:address/street "lucky street"})
;; => #:address{:address-id 301}

(pco/defresolver address-address-id->person-address-id 
  [{:address/keys [address-id]}]
  {::pco/output [:person/address-id]}
  {:person/address-id address-id})
(address-address-id->person-address-id {:address/address-id 302})
;; => #:person{:address-id 302}

(pco/defresolver person-address-id->persons
  [{:keys [:person/address-id]}]
  {::pco/output [:person/person-id
                 :person/first-name
                 :person/email
                 :person/address-id]}
  (->> person-db
       (filter #(= address-id
                   (-> % val :person/address-id)))
       vals))
(person-address-id->persons {:person/address-id 301})
;; => (#:person{:person-id 1, :first-name "Darren", :address-id 301}
;;     #:person{:person-id 2, :first-name "Jiyoung", :address-id 301})


(def index
  (pci/register [address-street->address-ids
                 address-address-id->person-address-id
                 person-address-id->persons]))

(p.eql/process
 index
 {:address/street "lucky street"}
 [:person/first-name]) ;; ERROR
Each of these resolvers returns expected values, but the last eql query makes an error. Error message says in more detail,
1. Caused by clojure.lang.ExceptionInfo
   Resolver petunia.graph/person-address-id->persons returned an
   invalid response: (#:person{:person-id 1, :first-name "Darren",
   :address-id 301} #:person{:person-id 2, :first-name "Jiyoung",
   :address-id 301})

kokonut23:06:24

It seems only the resolver that returns collection (multiple values by filter) does not work. Others that return single value by key for hashmap do work fine. Probably there is something I am doing incorrectly. Maybe pco/output part for person-address-id->persons?

sheluchin23:06:12

@U022N1DU7GQ It looks like you are trying to use inputs everywhere rather than using parameters. Check the link I posted. You want to use something like (pco/params env) to pull params out and use them to filter the return value of your resolver. I think using inputs for this isn't the right approach, you just want to ask for something like the first name, last name, and address of all people that live on some particular street.

💯 2
kokonut00:06:16

Amazing. I get it. I am trying it now, but thanks first!