pathom

plexus 2023-08-31T09:44:57.787039Z

hey folks, pretty new to Pathom so please ignore my ignorance 🙂 is there a way to access inputs from a parent resolver? what I'm dealing with is a set of resolvers that proxy to a third party API, for which the caller provides an API key in the EQL input data. I can access that api key in the top-level resolver, but when I try to resolve nested data I'm stuck.

plexus 2023-08-31T11:33:57.350099Z

a more concrete example, say I have users which are part of user groups. Users have an id, but the id is only unique within a given group, so to retrieve more information about the user I need both the user id and the group id

plexus 2023-08-31T11:34:00.852189Z

(pco/defresolver user-groups []
  {:groups [{:group/id 1}
            {:group/id 2}
            {:group/id 3}]})

(pco/defresolver group-users [{:group/keys [id]}]
  {:group/users [{:user/id (str id "a")}
                 {:user/id (str id "b")}]})

(pco/defresolver user-data [????]
  ;; fetch data for a user based on its group/id and user/id
  {:user/data (fetch-user-data group-id user-id)}
  )

plexus 2023-08-31T11:35:34.032409Z

(p.eql/process env [{:groups [{:group/users [:user/id :user/data]}]}])

plexus 2023-08-31T11:36:19.371599Z

the only way I've found to make this contextual information available down the tree is to repeat it at every level

plexus 2023-08-31T11:36:59.163599Z

(pco/defresolver group-users [{:group/keys [id]}]
  {:group/users [{:user/group-id id
                  :user/id (str id "a")}
                 {:user/group-id id
                  :user/id (str id "b")}]})

pithyless 2023-08-31T14:28:16.852729Z

> Users have an id, but the id is only unique within a given group I think there is a hidden "entity" in your description: the "group-membership" (group + user).

{:group/members [{:group-member/id "???"
                  :group-member/user-id 123
                  :group-member/group-id 345}]}
Since you don't have this explicit, you've got an impedance mismatch. So, I think the trick is to just figure out which way to model this invisible entity works best for you and DX ergonomics (instead of thinking how to "pass down" the group-id). :user/group-id feels the least useful (since it's not a property of the user, but of the membership) and I would either pass the values directly:
{:group/users [{:user/id 123, :group/id 345}]}
or maybe even consider creating some custom ID via e.g. a tuple (which may never be exposed publicly, but can still be used to resolve other attributes):
{:group/users [{:group/member [123 345]}]}

plexus 2023-08-31T11:37:17.585369Z

is that how people solve this?

wilkerlucio 2023-08-31T13:25:47.695569Z

hello @plexus, welcome! as you mentioned, forwarding down is one way, if the user can have only a single group you could also make a resolver to navigate to it. for the token scenario, in general people have it in the env instead of input, so its globally available (but if that info is coming from another resolver, you might need two requests, first to fetch it, then to set it at env for the next requests)

wilkerlucio 2023-08-31T13:27:37.994519Z

a third more involved solution would be using a mutable thing at env, there you could set on the resolver return, this could a simple atom application if the thing is global, but if in different sections you need different info, them the atom can be in the format of {PATH THING-VALUE}, you can access the current path from env at any time, so you could have an algorithm that looks for path parts (starting at current and removing from the tail on each iteration, until path is found or reach the root), makes sense?