Fork me on GitHub
#graphql
<
2023-09-06
>
Nikolas S.21:09:57

Hello I am quite new to Clojure, Graphql and the Lacinia library, so please forgive me If I am overlooking something obvious. But I wanted to ask if it is possible to use the same resolver for a "top-level" query and nested query. I am not sure how much code is necessary to get an understanding of what I am struggling with but my resolver map looks like this:

(defn resolver-map []
  {:Query/account (account-by-id)
   :Account/registeredServices (services-by-account-id)
   :Query/accountServicesByAccountID (services-by-account-id)})
And the resolver function that I have a problem with is services-by-account-id it only works as intended when I query "accountServicesByAccountID" i.e.
(q "{ account(id: 1) { id name registeredServices {name id} }}" ) ;; returns empty Vector for registeredServices
(q "{ accountServicesByAccountID(id: 1) { id name }}" ) ;; Works as intended
The resolver function looks like this:
(defn services-by-account-id
  []
  (fn [_ args _]
    (map remap-account-service (queries/get-account-services (:id args)))))
I noticed that if were to print the unused arguments in the working one args is {:id} (as intended), but when called as a nested resolver the third argument is the map that I want to use. I hope that makes sense. p.s. I also checked the documentation and saw the approach with executor/selects-field? for having different resolvers for nested queries, but that is something I want to implement later on.

hlship23:09:55

Your close, but not quite on the right track. The Query/ fields exist to start with nothing (except, perhaps, field parameters) and produce *something. Other resolvers start with a something and produce related data ... often by extracting part of the raw data (such as a database id) and using it to query further data. So Query/accountServicesByAccountId maybe gets an :id parameter, and returns (I have to guess here) some AccountServices. Account/registeredServices willb e passed a previously resolved Account object, and finds the AccountServices for that account (no parameter, just the parent field's resolved value). Also, why are you adding an extra level of indirection (services-by-account-id could just be a resolver function, not a function that returns a resolver function).

🙌 2
hlship23:09:35

Generally, I would factor what you have into two independent, but trivial, field resolver functions that call into a shared utility function.