(ns example (:require [com.wsscode.pathom3.connect.indexes :as pci] [com.wsscode.pathom3.connect.operation :as pco] [com.wsscode.pathom3.interface.eql :as p.eql])) (def companies {1 {:company/id 1 :company/name "ACME Inc."}}) (def locations {1 {:location/id 1 :location/name "Toon Town" :location/problems 2 :location/deleted false :location/company 1} 2 {:location/id 2 :location/name "Snailville" :location/problems 0 :location/deleted false :location/company 1} 3 {:location/id 3 :location/name "Laffy Forest" :location/problems 1 :location/deleted true :location/company 1}}) (pco/defresolver company-attrs [env {:company/keys [id]}] {::pco/input [:company/id] ::pco/output [:company/name]} (select-keys (get companies id {}) [:company/name])) (pco/defresolver location-attrs [env {:location/keys [id]}] {::pco/input [:location/id] ::pco/output [:location/name :location/problems :location/deleted]} (select-keys (get locations id {}) [:location/name :location/problems :location/deleted])) (pco/defresolver company-locations [env {:company/keys [id]}] {::pco/input [:company/id] ::pco/output [{:company/locations [:location/id]}]} (let [where-pred (get (pco/params env) :where (constantly true))] {:company/locations (->> (vals locations) (filter #(and (= (:location/company %) id) (where-pred %))) (mapv #(select-keys % [:location/id])))})) (pco/defresolver company-problems [env {:company/keys [locations]}] {::pco/input [{`(:company/locations {:where ~(complement :location/deleted)}) [:location/problems]}] ::pco/output [:company/problems]} {:company/problems (reduce (fn [acc {:location/keys [problems]}] (+ acc problems)) 0 locations)}) (def indexes (pci/register [company-attrs location-attrs company-locations company-problems])) (comment (p.eql/process indexes {:company/id 1} [:company/id :company/name :company/problems {:company/locations [:location/id :location/name :location/problems]}]) ;; The above returns the following, filtering out the Laffy Forest ;; location because the :company/problems resolver ran and included ;; the attributes from it's input query of the :company/locations attribute. ;; I would expect the company-locations resolver to run twice, once ;; for each set of params. The node shouldn't be considered equivalent ;; with different params. {:company/id 1, :company/name "ACME Inc.", :company/problems 2, ;; correctly counted the problems without deleted location :company/locations ;; deleted location was dropped although it wasn't requested to be. ;; If :company/problems is removed from the query it will come back as ;; part of this result [{:location/id 1, :location/name "Toon Town", :location/problems 2} {:location/id 2, :location/name "Snailville", :location/problems 0}]} )