This function alone is relatively useless, we need more information to use it properly in a bigger system : We need to say what it transforms, and into what. Pathom already have this pattern in its resolver descriptors, I will try to reuse it.
I am trying to see how to deal with (-> user :person/written-articles (get 0) :article/authors (get 0) :person/full-name)
and being able to calculate the canonical path of the person’s name from user
given as the input.
Some bits of ideas …
;; Entity description.
;; - It shows where to find an entity in the local db,
;; - It enumerate its fields, making them usable in the template.
{:type :entity/person
:identifier :person/id
:path-fn (fn [person] [:person/by-id (:person/id person)])
:path [:person/by-id] ;; shorthand version of :path-fn
:index {:person/email :person/by-email} ;; in the db: {:person/by-email {:person/email :person/id, ...}}
:fields [:person/id
:person/email
:person/first-name
:person/last-name
:person/picture-url]}
{:type :entity/article
:identifier :article/id
:path [:article/by-id]
:fields [:article/id
:article/title
:article/date
:article/tags
{:article/authors [:person/id]} ;; pathom style description
:article/content]}
;; "virtual field" keyword, provided via Pathom resolvers.
;; This is a syntax sugar, just for the special case of a keyword. The general case is a function.
;; - It describes how to go from an entity to another one, by pretending that we just follow a key in a hash-map.
;; - The keywords in the output become usable inside the template.
;; - When we get to an entity, if it includes its identifier field(s), we know its path in the db from the entity's description.
;; - When we get to an entity's field, we know its relation to its entity, therefore its path in the db.
{:input #{:person/id}
:output [{:person/written-articles :entity/article}] ;; :entity/article expends to the vector of its fields
:transform person-id->written-articles}
{:input #{:person/first-name :person/last-name}
:output [:person/full-name]
:transform (fn [_ {:person/keys [first-name last-name]}]
(str first-name " " last-name))}
I did not decide how to represent the “virtual field” and the functions which are usable in the template. I will see later. Maybe I should start implementing the parts which I am confident with first, and see later for what is missing. — End of today’s brainstorming.
@yogthos I am thinking about describing the syntax in Vrac’s template using Minimallist. Before I start, I would like to know if you think that the syntax is good enough or if it requires some changes.
I plan to support those following constructs: if, when, for, let, case, cond, ->, ->>, and destructurations.
Oh, and I am going to regroup all the brainstorming ideas into a coherent documentation. Without it, in 2 weeks I would forget everything.