Fork me on GitHub
#pathom
<
2020-03-16
>
yenda07:03:45

it depends on how much you want to hammer your db, I have resolvers that compose a fat query and return most of the data already to minimize back and forth

kwladyka12:03:39

(utils/request-eql '[{[:shop/uuid #uuid"00000000-0000-0000-0000-000000000000"] [* :shop/name]}])
return
#:shop{:uuid #uuid"00000000-0000-0000-0000-000000000000",
       :name "redshop",
       :engine "atomstore",
       :config {:foo "bar"},
       :updated_at #inst"2020-03-15T23:03:19.353-00:00",
       :created_at #inst"2020-03-15T23:03:19.353-00:00"}
but
(utils/request-eql '[{[:shop/uuid #uuid"00000000-0000-0000-0000-000000000000"] [*]}])
return
#:shop{:uuid #uuid"00000000-0000-0000-0000-000000000000"}
For resolver:
(pc/defresolver get-shop [env {:shop/keys [uuid]}]
                {::pc/input #{:shop/uuid}
                 ::pc/output [:shop/uuid :shop/name :shop/engine :shop/config]}
                (shop-biz/get-shop uuid))
How to get ALL values? I was trying also
(utils/request-eql '[[:shop/uuid #uuid"00000000-0000-0000-0000-000000000000"]])

kwladyka12:03:48

Is it a bug?

kwladyka12:03:11

* works if I want any other value like :shop/name but if on it does nothing

kszabo12:03:40

* just returns the current entity

kszabo12:03:54

it just means, any resolvers that got called, I want all the data

kszabo12:03:16

if you just supply * no resolvers will be called, hence you only get what you provided for base entity

kszabo12:03:00

there is no way to say I want all direct outputs (or n-levels deep) from this attribute that I provided

kwladyka13:03:50

for [{::latest-product [*]}] I got

{::latest-product
 {:product/id 1,
  :product/title "Acoustic Guitar", 
  :product/price 199.99}}

kwladyka13:03:41

also output make me confuse because:

::pc/output [:shop/uuid :shop/name :shop/engine :shop/config]}
can return
#:shop{:uuid #uuid"00000000-0000-0000-0000-000000000000",
       :name "redshop",
       :engine "atomstore",
       :config {:foo "bar"},
       :updated_at #inst"2020-03-15T23:03:19.353-00:00",
       :created_at #inst"2020-03-15T23:03:19.353-00:00"}

kwladyka13:03:53

updated_at is not in output

kwladyka13:03:05

so this output looks a little like something to ingore

kwladyka13:03:11

besides of maybe informational purpose

kszabo13:03:00

::pc/output is just describing that these things can be returned (there can be more)

kszabo13:03:17

and * works as I described, you are using it inside a join

kszabo13:03:54

anyway that is for exploratory cases and shouldn’t be the way you use Pathom in real code

kwladyka13:03:48

(pc/defresolver get-shop [env {:shop/keys [uuid]}]
                {::pc/input #{:shop/uuid}
                 ::pc/output [:shop [:shop/uuid :shop/name :shop/engine :shop/config]]}
                {:shop (shop-biz/get-shop uuid)})
(pc/defresolver get-shop [env {:shop/keys [uuid]}]
                {::pc/input #{:shop/uuid}
                 ::pc/output [:shop/uuid :shop/name :shop/engine :shop/config]}
                (shop-biz/get-shop uuid))
Do you see any pros / cons between this 2 ver.? So return data in :shop vs directly

wilkerlucio13:03:13

as people described, flat is better, but just a hint, the first example is missing the map {} to make the join between :ship and the nested properties

kwladyka13:03:00

at that moment I am mainly focus on testing part, so no write FE side

kwladyka13:03:11

so can not see some issues

kszabo13:03:40

Keep your resolvers flat, reserve nesting for joins (when you need to return multiple maps/etc. like {:user/friends [:user/id]} )

👍 4
kszabo13:03:32

this could be useful

kwladyka14:03:23

hmm after all I think get-shop doesn’t make sense. get-shops is probably what I want.

kwladyka14:03:53

Do you use create-shop / create-shops ? I know this questions sounds dump, but pathom in my feeling gives possibilities of different approaches which can be still simple

eoliphant14:03:00

id say it depends on your use cases. Do you have scenarios where you bulk create “shops”

kwladyka14:03:42

probably not, but I would like to keep the same rule for all queries. plural or singular, but not both.

eoliphant14:03:14

yeah, you might just want to experiment a bit, especially for my mutations, i tend to try to let them reflect the ‘commands’ in my domain. nice thing is that if you follow the guidance of doing most of the work in separate functions that your resolvers call, it’s a little easier to come up with composable bits that are easier to leverage in whatever resolver approach you settle on

kwladyka14:03:19

after all I think I will do get-items but create update delete 1 item

kwladyka14:03:16

Just because managing state is harder and debugging 1 create is easier, than many

souenzzo15:03:21

In my experience, there is no create operation in any system create-user usually will create user, session, message buy-item will create cart itemInCart ... that CRUD thing simply don't exists nor help

eoliphant14:03:37

another thing i’ve found is that resolver names are themselves less of a big deal, for instance, i’ve got some code that I use to auto-generate some of them, the real deal is what they’re contributing to the resolver graph.

eoliphant14:03:45

sure, go with that, and see how it works out for you.. and like i said, if your resolvers and mutations are delegating most of their work to helpers, say a create-many-items shouldn’t be a big lift if you end up needing it

eoliphant15:03:03

i’ve had situations where pretty much all of the ‘app driven’ stuff was more or less your model, create-one but later i needed some bulk import capability. So just whipped up some code that used my create-one helper functions for a bulk mport process that was run by ops in the background

kwladyka15:03:23

BTW what is your pattern to get all items vs selected items?

(utils/request-eql [{[:shop/uuids #{}] [:shops]}])
I am thinking about send empty uuids as “get all”

eoliphant15:03:23

i use explicit {:all-xxx …} resolvers for now

👍 4
kwladyka15:03:22

(utils/request-eql [{[:shop/uuids :all] [:shops]}])
I can also use :all or whatever

eoliphant15:03:23

in my case, i’m using datomic on the backend, and this little bit of meta/domain modeling code i wrote, so those resolvers by and large just get generated. I’ve found that the cases where i need one v many tend to not really overlap too much so by applying consistently i’m generally ok.

eoliphant15:03:12

yeah that’s the beauty of it, you can do almost whatever you want. though your mileage will of course vary. One thing you might want to play around with in your approach is passing whatever params you need (paging, limits, whatever).

kwladyka15:03:14

I changed this to :all for now, but I will see

kwladyka15:03:53

(let [shop #:shop{:uuid #uuid"11111111-1111-1111-1111-111111111111"
                  :name "test shop"
                  :engine "engine"
                  :config "{\"abc\": \"def\"}"}]
  (is (= shop
         (utils/request-eql [{'(shop/update shop)
                              [:shop/uuid :shop/name :shop/engine :shop/config]}]))
      "update shop"))
How do you achieve
'(shop/update shop)
I mean I want to call mutation, but I want to have shop from let

kwladyka15:03:12

I use pr-str to conver this into string

kwladyka15:03:22

or do you know better method to generate eql query?

kwladyka15:03:22

I can always do

(list 'shop/update shop)
but this is ugly

kwladyka15:03:34

hmm but probably have to

kwladyka15:03:39

oh I can use

`(shop/update ~shop)

souenzzo16:03:51

pr-str i think that is the default method to generate a string from edn but usually we use transit once it runs on browser

kwladyka20:03:46

query

(let [shop #:shop{:uuid #uuid"11111111-1111-1111-1111-111111111111"
                  :name "test shop"
                  :engine "engine"
                  :config {:abc "def"}}]
  (utils/request-eql [{`(shop/update ~shop) [:shops [:shop/uuid :shop/name :shop/engine :shop/config]]}]))
response
#:shop{update
       {[:shop/uuid :shop/name :shop/engine :shop/config]
        #:shop{:uuid :shop/name},
        :shops
        [#:shop{:uuid #uuid "11111111-1111-1111-1111-111111111111",
                :name "test shop",
                :engine "engine",
                :config {:abc "def"},
                :updated_at #inst "2020-03-16T20:33:21.279-00:00",
                :created_at #inst "2020-03-16T20:18:03.964-00:00"}]}} 
^ what #:shop{:uuid :shop/name} doing here? defs
(pc/defmutation update-shop [env params]
                {::pc/sym 'shop/update
                 ::pc/params #{:shop/uuid :shop/name :shop/engine :shop/config}
                 ::pc/output [:update]}
                (shop-biz/update-shop params)
                {:shop/uuids #{"11111111-1111-1111-1111-111111111111"}})

(pc/defresolver get-shops [env {:shop/keys [uuids]}]
                {::pc/input #{:shop/uuids}
                 ::pc/output [:shops [:shop/uuid :shop/engine]]}
                {:shops (shop-biz/get-shops uuids)})

kwladyka20:03:10

How to code this correctly? So update-shop return shop with get-shops

kwladyka21:03:23

I have to say after all new doc makes me very confused. I have no idea how to use pathom. Maybe I will try to read old doc tomorrow.

eoliphant21:03:51

couple things, i think you want your mutation to return a single ident for the updated shop [:shop/uuid 1111]

eoliphant21:03:21

then have your resolver output just be [:shop/uuid :shop/engine] and just return (shop-biz/get-shops uuids)