Skip to content

Instantly share code, notes, and snippets.

@mauricioszabo
Last active March 14, 2022 16:30
Show Gist options
  • Save mauricioszabo/fa4295aaf0f658cace018ec1170cd4ea to your computer and use it in GitHub Desktop.
Save mauricioszabo/fa4295aaf0f658cace018ec1170cd4ea to your computer and use it in GitHub Desktop.
Test GraphQL + Pathom3
(ns graphql-test.core
(:require [malli.core :as m]
[clojure.string :as str]
[com.wsscode.misc.coll :as coll]
[com.wsscode.pathom3.interface.eql :as p.eql]
[com.wsscode.pathom3.connect.operation :as connect]
[com.wsscode.pathom3.connect.indexes :as indexes]
[com.walmartlabs.lacinia :as lacinia]
[com.walmartlabs.lacinia.util :as lacinia-util]
[edn-query-language.core :as eql]
[com.walmartlabs.lacinia.schema :as lacinia-schema])
(:gen-class))
(def droids
{"R2D2" {:name "R2-D2"
:appears_in [1 2 3 4 5 6 7]
:friends-of ["Luke" "Leia"]
:primary_function ["Astro"]}})
(def hoomans
{"Luke" {:name "Luke Skywalker"
:appears_in [4 5 6 7 8]
:friends-of ["Leia" "R2D2" "Han"]
:home_planet "Tatooine"}
"Leia" {:name "Leia Organa"
:appears_in [3 4 5 6 7 8]
:friends-of ["Luke" "Han"]
:home_planet "Naboo"}
"Han" {:name "Han Solo"
:appears_in [4 5 6 7]
:friends-of ["Leia"]
:home_planet "???"}})
(connect/defresolver human-resolver [env {:human/keys [id]}]
{::connect/output [:human/name :human/appears_in :human/home_planet :human/friends-of]}
(-> hoomans
(get id)
(update-keys #(keyword "human" (name %)))))
(connect/defresolver human-friend-resolver [{:human/keys [friends-of]}]
{:human/friends
(->> friends-of
(map (fn [id]
(-> hoomans
(get id)
(update-keys #(keyword "character" (name %))))))
(filter seq))})
(connect/defresolver friend-resolver [{:character/keys [friends-of]}]
{:character/friends
(->> friends-of
(map (fn [id]
(-> hoomans
(get id)
(update-keys #(keyword "character" (name %))))))
(filter seq))})
(connect/defresolver droid-resolver [env {:droid/keys [id]}]
{::connect/output [:droid/name :droid/appears_in :droid/home_planet :droid/friends-of]}
(-> droids
(get id)
(update-keys #(keyword "droid" (name %)))))
#_
(lacinia/execute (gql-schema-from-pathom3 idx)
"query {
human(id: \"R2D2\") {
name
}
}"
nil nil)
(def idx (indexes/register [human-resolver friend-resolver human-friend-resolver droid-resolver]))
#_
(p.eql/process idx {:human/id "Leia"} [:human/name :human/id {:human/friends [:character/name {:character/friends [:character/name]}]}])
#_
(p.eql/process idx {:human/id "Leia"} [:human/name :human/id {:human/friends [:character/name :character/friends]}])
(defn gql-entity-fields [env]
(let [attributes
(->> env
::indexes/index-attributes
keys
(into {}
(comp (filter keyword?)
(map (fn [attr]
(prn :ATTR attr)
(coll/make-map-entry
(name attr)
{:type :human}))))))]
attributes))
(defn selection->eql [{:keys [selections]}]
(into []
(map (fn [{:keys [qualified-name arguments leaf?] :as selection}]
(let [field-name'
(cond-> qualified-name
(seq arguments)
(eql/parameterize arguments))]
(if leaf?
field-name'
{field-name' (selection->eql selection)}))))
selections))
(defn eql-resolver-map
[env]
{:query/entity
(fn [{::lacinia/keys [selection] :as context} args value]
(let [entity (-> (or args {})
(update-keys #(keyword (name (:field-name selection)) (name %))))
_ (prn :EQL (selection->eql selection))
result (p.eql/process env entity (selection->eql selection))]
(prn :RES result)
(update-keys result (comp keyword name))))})
(def from-pathom
'{:enums
{:episode
{:description "The episodes of the original Star Wars trilogy."
:values [:NEWHOPE :EMPIRE :JEDI]}}
:interfaces
{:character
{:fields {:id {:type String}
:name {:type String}
:appears_in {:type (list :episode)}
:friends {:type (list :character)}}}}
:objects
{:droid
{:implements [:character]
:fields {:id {:type String}
:name {:type String}
:appears_in {:type (list :episode)}
:friends {:type (list :character)}
:primary_function {:type (list String)}}}
:human
{:implements [:character]
:fields {:id {:type String}
:name {:type String}
:appears_in {:type (list :episode)}
:friends {:type (list :character)}
:home_planet {:type String}}}}
:queries
{:human {:type (non-null :human)
:args {:id {:type String
:default-value "1001"}}
:resolve :query/entity}
:droid {:type (non-null :droid)
:args {:id {:type String}}
:resolve :query/entity}}})
(defn gql-schema-from-pathom3
[env]
(def env env)
(-> from-pathom
(lacinia-util/attach-resolvers (eql-resolver-map env))
lacinia-schema/compile))
#_
(lacinia/execute (gql-schema-from-pathom3 idx)
"query {
human(id: \"Leia\") {
name
}
}"
nil nil)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment