This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-11
Channels
- # announcements (3)
- # aws (3)
- # babashka (79)
- # beginners (105)
- # calva (10)
- # chlorine-clover (22)
- # clj-kondo (12)
- # cljs-dev (39)
- # clojure (52)
- # clojure-europe (1)
- # clojure-spec (15)
- # clojure-uk (12)
- # clojurescript (47)
- # conjure (93)
- # data-science (1)
- # datomic (10)
- # emacs (6)
- # figwheel-main (14)
- # fulcro (30)
- # instaparse (3)
- # kaocha (2)
- # lambdaisland (3)
- # malli (2)
- # meander (6)
- # off-topic (27)
- # pathom (14)
- # perun (1)
- # reagent (15)
- # shadow-cljs (69)
- # slack-help (2)
- # spacemacs (5)
- # test-check (23)
- # vim (9)
Is it fine to use for `:pc/input` vector instead of `#{}`? Or on the other hand for `:pc/output` use `#{}` instead of vector, which will be even more useful for me. It looks like it works, but do I miss something? There has to be some reason when it is done in that way in doc right?
(s/describe ::pc/input)
=> (coll-of :com.wsscode.pathom.core/attribute :kind set?)
(s/describe ::pc/output)
=>
(or
:attribute-list
(coll-of :com.wsscode.pathom.connect/out-attribute :kind vector? :min-count 1)
:union
(map-of :com.wsscode.pathom.connect/attribute :com.wsscode.pathom.connect/output))
It's values are specifiedDo you see this patterns also for your app when you have to use:
(def shop-keys [:shop/uuid :shop/name :shop/engine :shop/config])
without uuid
[:shop/name :shop/engine :shop/config]
as a vector and set?as long as it is macro anyway I would like to see this converting to the right type (set / vector)
(def shop-keys-without-uuid #{:shop/name :shop/engine :shop/config})
(def shop-keys (into [:shop/uuid] shop-keys-without-uuid))
(defn ->spec [shop]
(s-utils/map-coercion
{:shop/uuid uuid/as-uuid
:shop/config json/read-str}
shop))
(defn ->eql [shop]
(-> (update shop :shop/uuid str)
(dissoc :shop/created_at :shop/updated_at)))
(pc/defmutation create-shop! [env shop]
{::pc/sym 'shop/create!
::pc/params shop-keys-without-uuid
::pc/output shop-keys}
(->eql (shop-db/create-shop! (->spec shop))))
(pc/defmutation update-shop! [env shop]
{::pc/sym 'shop/update!
::pc/params (set shop-keys)
::pc/output [:shop/uuid]}
(shop-db/update-shop! (->spec shop))
(select-keys shop [:shop/uuid]))
(pc/defresolver get-shop [env params]
{::pc/input #{:shop/uuid}
::pc/output (vec shop-keys-without-uuid)
::pc/transform pc/transform-batch-resolver}
(shop-db/get-shops-by-uuid (->> (map :shop/uuid params)
(map (partial s-utils/safe-coercion uuid/as-uuid))
(set))))
(pc/defresolver all-shops [env _]
{::pc/output [{:shops shop-keys}]}
{:shops (mapv ->eql (shop-db/get-all-shops))})
(pc/defmutation delete-shop [env {:shop/keys [uuid]}]
{::pc/sym 'shop/delete
::pc/params #{:shop/uuid}
::pc/output [:deleted?]}
{:deleted? (shop-db/delete-shop uuid)})
This dance with set
and vec
and how def
looks show what I mean.In your case, create-shop!
, get-shop
, and all-shops
all return [:shop/name :shop/engine :shop/config]
. I find this approach counter-intuitive, as subtle changes in implementation of these resolvers could hide bugs over time. I prefer to have create-shop!
, all-shops
, and update-shop!
all return just :shop/uuid
; and then you only need one get-shop
that knows how to resolve all the other attributes. Easier to isolate logic/authorization/etc. to one place and you no longer have to worry about code redundancy. ;]
hmm while database performance and time response is not the issue, because of the 2x DB query it is a solution 🙂
@wilkerlucio regarding dynamic resolvers, do all items in ::pcp/requires
have equivalence in ::pcp/foreign-ast
and vice versa? Also, what is the use case for those ::pcp/requires
?
pcp/requires determines what is expected to be on the output of this node call