pathom 2023-04-20

Newbie question: With the following 'database':

(def users
  {1 #:user{:id 1
            :name "joe"
            :age 22}
   2 #:user{:id 2
            :name "bob"
            :age 10}})
how to write resolver and query where I pass in a cutoff age like: {:user/cutoff-age 15} and get back only "joe"?

Just rename the parameter and add another one:

(pco/defresolver all-users
  [env _]
  {::pco/output
   [{:user/all
     [:user/id
      :user/name
      :user/age]}]}
  (let [{:keys [below-age above-age] (pco/params env)]
    {:user/all
     (vec
       (cond->> (vals users)
         below-age (filter #(< (:user/age %) below-age))
         above-age (filter #(< above-age (:user/age %)))))}))
Then you can do:
['(:user/all {:above-age 15, :below-age 42})]

You can do many things with this, like sorting, limiting, or paging.

['(:user/all {:above-age 15, :below-age 42, :sort-by-key :user/name, :limit 5, :offset 10})]

(pco/defresolver all-users
  [env _]
  {::pco/output
   [{:user/all
     [:user/id
      :user/name
      :user/age]}]}
  (let [{:keys [below-age above-age sort-by-key offset limit] (pco/params env)]
    {:user/all
     (vec
       (cond->> (vals users)
         below-age   (filter #(< (:user/age %) below-age))
         above-age   (filter #(< above-age (:user/age %))
         sort-by-key (sort-by sort-by-key)
         offset      (drop offset)
         limit       (take limit)))}))

if you wanna work on some more generic / full feature thing, you can see https://walkable.gitlab.io/ for inspiration

hello fenton, this is one way you can implement such filter:

(ns com.wsscode.pathom3.fenton-demo
  (:require [com.wsscode.pathom3.connect.indexes :as pci]
            [com.wsscode.pathom3.connect.operation :as pco]
            [com.wsscode.pathom3.interface.eql :as p.eql]))

(def users
  {1 #:user{:id   1
            :name "joe"
            :age  22}
   2 #:user{:id   2
            :name "bob"
            :age  10}})

(pco/defresolver all-users
  [{:user/keys [cutoff-age]
    ; this will make this attribute optional
    :or        {cutoff-age nil}}]
  {::pco/output
   [{:user/all
     [:user/id
      :user/name
      :user/age]}]}
  {:user/all
   (cond->>
     (vec (vals users))

     cutoff-age
     (filterv #(>= (:user/age %) cutoff-age)))})

(def env
  (-> {}
      (pci/register all-users)))

(comment
  ; gets all users
  (p.eql/process env [:user/all])

  ; only over 15
  (p.eql/process env {:user/cutoff-age 15} [:user/all]))

and here is another way, using params (this option makes easier for the user to customize it in the query at any level):

(ns com.wsscode.pathom3.fenton-demo
  (:require [com.wsscode.pathom3.connect.indexes :as pci]
            [com.wsscode.pathom3.connect.operation :as pco]
            [com.wsscode.pathom3.interface.eql :as p.eql]))

(def users
  {1 #:user{:id   1
            :name "joe"
            :age  22}
   2 #:user{:id   2
            :name "bob"
            :age  10}})

(pco/defresolver all-users
  [env _]
  {::pco/output
   [{:user/all
     [:user/id
      :user/name
      :user/age]}]}
  (let [cutoff-age (-> (pco/params env) :user/cutoff-age)]
    {:user/all
     (cond->>
       (vec (vals users))

       cutoff-age
       (filterv #(>= (:user/age %) cutoff-age)))}))

(def env
  (-> {}
      (pci/register all-users)))

(comment
  ; gets all users
  (p.eql/process env [:user/all])

  ; only over 15
  (p.eql/process env ['(:user/all {:user/cutoff-age 15})]))

🙏. Very kind of you.

no worries, let me know if you have any questions about the approaches

👍 1

How do we let the user specify in their query what they want to do with the age? age < X or age > X or X < age < Y?