-
-
Notifications
You must be signed in to change notification settings - Fork 62
Connect
Alpha - this feature is active development and the API might change.
Connect is high level reader on pathom, it providers an abstraction around data-fetching that enables declarative attribute mapping. I have an easier time explaining though examples, so let's start with one:
(ns pathom-docs.connect-hello
(:require [com.wsscode.pathom.core :as p]
[com.wsscode.pathom.connect :as p.connect]))
(def artists
{1 {:artist/id 1
:artist/name "Shpongle"
:artist/genre "psychill"}
2 {:artist/id 2
:artist/name "The Beatles"
:artist/genre "rock"}})
; this is the resolver function, using the params + env it
; should return a map proving the declared keys
(defn artist-by-id [env {:artist/keys [id]}]
(get artists id))
; create the indexes for Connect
(def indexes
(-> {}
; here we add our resolver to the indexes, the resolver must have a symbol with the fn
; and optional input, and an output containg the keys that are provided by this resolver
(p.connect/add `artist-by-id
#::p.connect {:input #{:artist/id}
:output [:artist/id :artist/name :artist/genre]})))
(def parser
(p/parser {::p/plugins [(p/env-plugin {::p/reader [p/map-reader
p.connect/all-readers]
; set the indexes
::p.connect/indexes indexes})]}))
(parser {} [{[:artist/id 1] [:artist/name]}])
; => {[:artist/id 1] #:artist{:name "Shpongle"}}
In connect, you define how inputs relate to outputs in terms of attributes. In previous example, a good way to read our resolver is: Given I have the key :artist/id
, I can provide you the keys :artist/id
, :artist/name
and artist/genre
. When you add a resolver that only needs a single input, it is indexes as an ident
, meaning you can use an ident
query to start from that attribute (as we did in the previous example).
Let's expand this example a little more, in a way to add an index that given an :artist/name
it can provide us with the :artist/id
:
(ns pathom-docs.connect-hello2
(:require [com.wsscode.pathom.core :as p]
[com.wsscode.pathom.connect :as p.connect]))
(def artists
{1 {:artist/id 1
:artist/name "Shpongle"
:artist/genre "psychill"}
2 {:artist/id 2
:artist/name "The Beatles"
:artist/genre "rock"}})
; our new index
(def artist-name->id
{"Shpongle" 1
"The Beatles" 2})
(defn artist-by-id [_ {:artist/keys [id]}]
(get artists id))
; the function that does the resolving, remember the resolves MUST return
; maps, always
(defn artist-name-to-id [_ {:artist/keys [name]}]
{:artist/id (artist-name->id name)})
; create the indexes for Connect
(def indexes
(-> {}
(p.connect/add `artist-by-id
#::p.connect {:input #{:artist/id}
:output [:artist/id :artist/name :artist/genre]})
; adding our new resolve, has a name as input and an id as output
(p.connect/add `artist-name-to-id
#::p.connect {:input #{:artist/name}
:output [:artist/id]})))
(def parser
(p/parser {::p/plugins [(p/env-plugin {::p/reader [p/map-reader
p.connect/all-readers]
; set the indexes
::p.connect/indexes indexes})]}))
(parser {} [{[:artist/name "Shpongle"] [:artist/genre]}])
; => {[:artist/name "Shpongle"] #:artist{:genre "psychill"}}
Connect is able to follow the dependencies to get the information.