Fork me on GitHub
#pathom
<
2020-11-30
>
rickmoynihan17:11:32

Question… is it possible to dynamically generate input and output properties / resolvers with pathom?

rickmoynihan17:11:54

Essentially I need to discover the attributes for my properties at run time. I think I would need to query my system to discover them dynamically before I resolve the queries.

rickmoynihan17:11:36

Is there a recommended way to do such a thing with pathom? From what I’ve seen it looks like properties must be coded up front, rather than discovered from your data

Björn Ebbinghaus21:11:21

Am I right that the viz full graph doesn’t show edges on a to-many relationship?

wilkerlucio21:11:24

not the nested parts, it connects with the attribute that has the list, but not the items (the indirect things)

JAtkins21:11:15

Maybe this is crazy/impossible, but can dynamic dependencies work? use case could be something like total-book-cost

pallet-cost, pallet-count, book-cost, book-count

total-book-cost:
  if present (pallet-cost, pallet-count) (* pallet-cost pallet-count)
  if present (book-cost, book-count) (* book-cost, book-count)
  else err

(total-book-cost {:pallet-cost 1 :pallet-count 2}) => 2

(total-book-cost {:book-cost 4 :book-count 4}) => 16

JAtkins21:11:17

It would (maybe?) be slow (having to trace if book-cost can be calculated from other params), but it could be useful if possible.

souenzzo22:11:53

@jatkin It's possible and AFIK, it's pretty optional performance

JAtkins22:11:48

Oh, duh. I'm an idiot 🙂. I thought there was much more ceremony here.

JAtkins22:11:16

Thanks very much for taking the time to write this out!

souenzzo22:11:23

+pathom3 example on the same gist Pathom3 is way more simpler 🙂

wilkerlucio22:11:31

just a warning with this approach, in case the entry has access to all 4 attributes, the result becomes uncertain

wilkerlucio22:11:28

one interesting thing that this case brings to mind is that you can also make a function to return resolvers, so another way to implement this:

parrot 2
wilkerlucio22:11:29

(defn attr-total-cost-resolver [attr]
  (let [cost-kw       (keyword (str attr "-cost"))
        count-kw      (keyword (str attr "-cost"))
        total-cost-kw (keyword (str "total-" attr "-cost"))
        sym           (symbol (str "total-book-cost-from-" attr))]
    [(pc/resolver sym
       {::pc/input  #{cost-kw
                      count-kw}
        ::pc/output [total-cost-kw]}
       (fn [_ input]
         {total-cost-kw (* (cost-kw input) (count-kw input))}))
     (pc/alias-resolver total-cost-kw :total-book-cost)]))

(let [;; Relevant part: the resolvers
      registers [(attr-total-cost-resolver "book")
                 (attr-total-cost-resolver "pallet")]
      ;; pathom2 parser. Pathom3 is simpler
      parser    (p/parser {::p/plugins [(pc/connect-plugin)]})
      env       {::p/reader               [p/map-reader
                                           pc/reader2
                                           pc/open-ident-reader
                                           env-placeholder-reader-v2] ;; I backported pathom3 placeholders to pathom2
                 ::pc/indexes             (pc/register {} registers)
                 ::p/placeholder-prefixes #{">"}}]
  (parser env `[{(:>/pallet {:pallet-cost 1 :pallet-count 2})
                 [:total-book-cost]}]))

wilkerlucio22:11:46

but still the same in consideration the same warning I said before

wilkerlucio22:11:57

I think a proper solution to it requires optional inputs, that's something planned for pathom 3, so you can ask for all attributes (as optionals) e than make your logic inside the resolver, so you have more control

wilkerlucio22:11:04

one way to archive this on pathom 2, is having a resolver that doesnt require any input, then from inside of it you call the parser again, and ask for the attributes (all of then), and work with this result, like:

(pc/defresolver total-book-cost [{:keys [parser] :as env} _]
  {::pc/output [:total-book-cost]}
  (let [result (parser env [:book-cost
                            :book-count
                            :pallet-cost
                            :pallet-count])]
    ...))