This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-05-21
Channels
- # announcements (4)
- # beginners (47)
- # cider (7)
- # clj-kondo (9)
- # cljs-dev (16)
- # clojure (8)
- # clojure-dev (33)
- # clojure-europe (39)
- # clojure-germany (2)
- # clojure-my (1)
- # clojure-nl (1)
- # clojure-norway (18)
- # clojure-uk (6)
- # clojuredesign-podcast (8)
- # clojurescript (12)
- # cursive (9)
- # datomic (24)
- # docker (3)
- # fulcro (23)
- # hoplon (7)
- # hyperfiddle (2)
- # java (5)
- # jvm (3)
- # leiningen (9)
- # lsp (6)
- # off-topic (75)
- # pathom (17)
- # polylith (21)
- # reitit (1)
- # rewrite-clj (11)
- # scittle (2)
- # shadow-cljs (57)
- # uncomplicate (6)
- # yamlscript (27)
hey all, I'm new to pathom, and reading the https://pathom3.wsscode.com/docs/resolvers/#nested-inputs about nested input, it says:
When Pathom is planning, it will verify if a sub-query part reachable. If there is no available path to fulfill the nested part, the planner will discard that path, avoiding running unnecessary work on the runner.
You can try this by asking for a nested property that doesn't exist.
I have taken the example and tried reaching a missing attribute, changing :player/score
to :player/score2
:
(pco/defresolver top-players-avg
"Compute the average score for the top players using nested inputs."
[{:keys [game/top-players]}]
; we have to make the nested input explicit
{::pco/input [{:game/top-players [:player/score2]}]}
{:game/top-players-avg-score
(let [score-sum (transduce (map :player/score2) + 0 top-players)]
(double (/ score-sum (count top-players))))})
when executing, I'm getting:
; Execution error (ExceptionInfo) at com.wsscode.pathom3.connect.planner/verify-plan!* (planner.cljc:1694).
; Pathom can't find a path for the following elements in the query: [:player/score2] at path [:game/top-players]
why is that?I thought it would just ignore it. Maybe I have understood the following wrong:
When Pathom is planning, it will verify if a sub-query part reachable. If there is no available path to fulfill the nested part, the planner will discard that path, avoiding running unnecessary work on the runner.
I’m super confused also. I have no clue what the docs are trying to say here
and while at it, why does it state that batch resolvers solve the N+1 problem? there are still N+1 reqs, they are just executed concurrently
Some clues here: https://github.com/wilkerlucio/pathom3-docs/commit/5292190ea4dbc9df4e3e2e8b6a70734a6a8be81c
> and while at it, why does it state that batch resolvers solve the N+1 problem? there are still N+1 reqs, they are just executed concurrently
batch resolvers are executed only once but receive multiple sibling inputs and return multiple sibling outputs. Because the resolver controls the “mapv”, it can do something other than what would happen for a single input and output. Eg select * from t where id=?
N+1 query per input can be where id in (…)
single query for all.
hello, about the sub-query part reachable, its when planning for nested inputs, consider this example:
(ns com.wsscode.pathom3.demos.sub-query-reachable
(:require [com.wsscode.pathom3.connect.indexes :as pci]
[com.wsscode.pathom3.connect.operation :as pco]
[com.wsscode.pathom3.interface.eql :as p.eql]))
(def users-db
{1 {:user/id 1
:user/name "John"}
2 {:user/id 2
:user/name "Doe"}})
(pco/defresolver users []
{:app/users [{:user/id 1}
{:user/id 2}]})
(pco/defresolver products []
{:app/products [{:product/id 1}]})
(pco/defresolver user-by-id [{:user/keys [id]}]
{::pco/output [:user/name]}
(get users-db id))
(pco/defresolver all-user-names [{:keys [app/users]}]
{::pco/input [{:app/users [:user/name]}]}
{:app/all-user-names (reduce str (map :user/name users))})
(def env
(-> {}
(pci/register [users user-by-id products all-user-names])))
(comment
(p.eql/process env [:app/all-user-names]) ; => {:app/all-user-names "JohnDoe"})
all-user-names
has a nested input, which works fine, because it asks for :user/name
from :app/users
, which is reachable using the :user/id
that's inside :app/users
nested itens
now, if we switch the all-user-names
to try to pull from products instead, like:
(pco/defresolver all-user-names [{:keys [app/products]}]
{::pco/input [{:app/products [:user/name]}]}
{:app/all-user-names (reduce str (map :user/name products))})
now, the items under :app/products
only have :product/id
, which means it can't reach for :user/name
in that context. this will cause the plan to fail because it finds no path that can reach the nested requirement
@U066U8JQJ That makes sense. Regarding the docs however: > If there is no available path to fulfill the nested part, the planner will discard that path, avoiding running unnecessary work on the runner.
> avoiding running unnecessary work on the runner I think that part is not helpful?
And then that whole statement is kinda pointless. If the path for the nested data cannot be reached, then your nested data cannot be reached
I guess I had too many impl details in my head, the point I was trying to make there is that because the planner fails early (by projecting the nested path and realizing there is no path) we don't have to run the top resolver to find out the missing data later, thats why I said > avoiding running unnecessary work on the runner
but I can see it can get clearer
That was my best guess. It looks relevant internally, but not at the consumer level