This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-11-03
Channels
- # announcements (2)
- # asami (1)
- # babashka (32)
- # beginners (125)
- # calva (4)
- # cider (1)
- # clj-kondo (16)
- # clj-together (1)
- # cljs-dev (15)
- # clojure (30)
- # clojure-australia (3)
- # clojure-europe (41)
- # clojure-italy (1)
- # clojure-losangeles (1)
- # clojure-nl (4)
- # clojure-spec (68)
- # clojure-uk (28)
- # clojurescript (36)
- # conjure (2)
- # cryogen (1)
- # cursive (2)
- # data-science (2)
- # datascript (2)
- # datomic (70)
- # events (2)
- # fulcro (11)
- # graalvm (1)
- # jobs (4)
- # kaocha (4)
- # leiningen (4)
- # malli (52)
- # meander (21)
- # off-topic (11)
- # pathom (7)
- # pedestal (17)
- # reagent (23)
- # reitit (5)
- # remote-jobs (5)
- # reveal (7)
- # shadow-cljs (24)
- # spacemacs (36)
- # sql (21)
- # vim (18)
- # xtdb (7)
I have a data modeling question.
let's say I have a bunch of entities, pet
s and owner
s. a pet
has an owner
, and owners
have pets. I have some pathom resolvers:
(pc/defresolver pet-resolver
[{:keys [db]} {:keys [:pet/id]}]
{::pc/input #{:pet/id}
::pc/output [{:pet [:pet/id :pet/name :pet/age ,,,]}]
(entity db [:pet/id id]))
(pc/defresolver owner-resolver
[{:keys [db]} {:keys [:owner/id]}]
{::pc/input #{:owner/id}
::pc/output [{:owner [:owner/id :owner/name :owner/age ,,,]}]
(entity d/b [:owner/id id]))
now, my idea was that: wouldn't it be easy if each pet
just had an :owner/id
on their entity in our system of record? this would allow to easily nest the :owner
resolver within a query for a pet:
(parse [{[:pet/id 123] [:pet/id :pet/name {:owner [:owner/id :owner/name]}]}])
;; => {[:pet/id 123] {:pet/id 123 :pet/name "Spot" :owner {:owner/id 9 :owner/name "lilactown"}}}
however, this introduces a problem in my system of record: if I'm using something like datomic/datascript, suddenly I have entities that have a key :owner/id
, which are not in fact owners. :owner/id
no longer specifies a unique identity of an entity
that property is fine, as long as the children entities only link to one owner
this could lead me to changing this in a couple of different ways. I could have a :pet/owner-id
key and a special pet-owner-resolver
which takes that key and looks up the owner.
(pc/defresolver pet-owner-resolver
[{:keys [db] {:keys [:pet/owner-id]}]
{::pc/input #{:pet/owner-id}
::pc/output [,,,]}
(entity db [:owner/id owner-id]))
However this is a lot of repetitive code, and my system actually has many different kinds of entities all of which can potentially have M:N relationships with each other.
another option is to nest the reference: I could have a :pet/owner
key which contains a map {:owner/id 9}
in my system of record. this way, the key isn't on an entity but rather it will be interpreted as a ref by datomic/datascript. This changes the query a bit:
(parse [{[:pet/id 123] [:pet/id :pet/name {:pet/owner [{:owner [:owner/id :owner/name]}]}]}])
;; => {[:pet/id 123] {:pet/id 123 :pet/name "Spot" :pet/owner {:owner {:owner/id 9 :owner/name "lilactown}}}}
This additional nesting... annoying? Tedious? It feels like wasted complexity> maybe `:pet/owner-id` and have an alias resolver to `:owner/id` ? that probably is the answer. I guess there are utilities for creating these that remove the boilerplate?
yes, it’s easy 🙂 you can create an a single direction alias or a bidirectional alias https://blog.wsscode.com/pathom/v2/pathom/2.2.0/connect/resolvers.html