Fork me on GitHub
#pathom
<
2021-04-26
>
Chris Rosengren03:04:35

Hi, trying out pathom 3, is this possible? Consider two different APIs providing the same IDs for some data, is there an automatic way of merging two output lists (by ID or composite attributes?): i.e: (defresolver get-names [] {::pco/output {::names [::id ::name]}} {::names [{::id 1 ::name "Foo"} {::id 2 ::name "Bar"}]}) (defresolver get-ages [] {::pco/output {::ages [::id ::age]}} {::ages [{::id 1 ::age 40} {::id 2 ::age 45}]}) I would like to write a query such as below, and have the results grouped by ID automatically, is this possible currently, and if not is my only option creating a third ::people resolver and manually group-by ::id (p.eql/process (pci/register [get-names get-ages]) [{::people [::id ::age ::name]}])

wilkerlucio04:04:00

hello Chris, it is possible, but the path you are taking here makes things a bit harder because the results are wrapped in lists, its easier if resolvers are at the entity level, so instead of get-names a get-name will be easier, same for get-ages, the simplest path would be something like:

(def names-by-id
  {1 "Foo"
   2 "Bar"})

(def ages-by-id
  {1 40
   2 45})

(pco/defresolver get-name [{::keys [id]}]
  {::name (get names-by-id id ::pco/unknown-value)})

(pco/defresolver get-age [{::keys [id]}]
  {::age (get ages-by-id id ::pco/unknown-value)})

(pco/defresolver all-people []
  {::pco/output [{::people [::id]}]}
  {::people (mapv #(array-map ::id %) (keys names-by-id))})

;; run query

(p.eql/process
  (pci/register [get-name
                 get-age
                 all-people])
  [{::people [::id ::age ::name]}])

Chris Rosengren04:04:04

Hi Wilker, thanks for the response, the problem is get-names and get-ages are processed responses from an API that I don't control (that only returns items in bulk).

wilkerlucio04:04:30

there are some tricks you can do in this case, let me write an example for you

wilkerlucio04:04:54

ok, here is an attribute dance you can do to handle this case:

(defn api-names []
  {:names [{::id 1 ::name "Foo"}
           {::id 2 ::name "Bar"}]})

(defn api-ages []
  {:ages [{::id 1 ::age 40}
          {::id 2 ::age 45}]})

(pco/defresolver names-bulk []
  {::pco/output [::names-index]}
  (let [{:keys [names]} (api-names)]
    {::names-index (->> (coll/index-by ::id names)
                        (coll/map-vals ::name))}))

(pco/defresolver get-name [{::keys [id names-index]}]
  {::name (get names-index id ::pco/unknown-value)})

(pco/defresolver ages-bulk []
  {::pco/output [::ages-index]}
  (let [{:keys [ages]} (api-ages)]
    {::ages-index (->> (coll/index-by ::id ages)
                       (coll/map-vals ::age))}))

(pco/defresolver get-age [{::keys [id ages-index]}]
  {::age (get ages-index id ::pco/unknown-value)})

(pco/defresolver all-people []
  {::pco/output [{::people [::id ::name]}]}
  {::people (:names (api-names))})

;; run query

(p.eql/process
  (pci/register [names-bulk
                 get-name
                 ages-bulk
                 get-age
                 all-people])
  [{::people [::id ::age ::name]}])

wilkerlucio04:04:15

its kinda what I sent before, but now has extra steps to load from a bulk list and index that in mid-process

wilkerlucio04:04:29

so this way you can access as if they were entity level things

wilkerlucio04:04:58

(just fixed a bug in the code I sent last)

wilkerlucio04:04:18

(`coll` is alias for com.wsscode.misc.coll, which is included with Pathom 3)

Chris Rosengren05:04:21

Much appreciated, thanks, also really like using the library in general

🙏 2