Skip to content

Connect

Wilker Lúcio edited this page Oct 14, 2017 · 10 revisions

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.

Clone this wiki locally