### Clojure: Pathom GraphQL Example (github_demo.cljs) Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc Includes a complete, runnable example of Pathom's GraphQL integration within a workspace environment. This file demonstrates practical usage and setup for the GraphQL features. ```clojure include::../workspaces/src/com/wsscode/pathom/workspaces/graphql/github_demo.cljs[] ``` -------------------------------- ### Pathom Initial Setup: Resolver and Mutation Configuration Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc This snippet shows the basic setup for Pathom's resolver and mutation dispatch mechanisms using multi-methods and factories. It also configures the parser environment with readers, dispatch functions, indexes, and plugins. ```clojure ; setup resolver dispatch and factory (defmulti resolver-fn pc/resolver-dispatch) (def defresolver (pc/resolver-factory resolver-fn indexes)) ; setup mutation dispatch and factory (defmulti mutation-fn pc/mutation-dispatch) (def defmutation (pc/mutation-factory mutation-fn indexes)) (def parser (p/parser {::p/env {::p/reader [p/map-reader pc/all-readers] ::pc/resolver-dispatch resolver-fn ::pc/mutate-dispatch mutation-fn ::pc/indexes @indexes ::db (atom {})} ::p/mutate pc/mutate ::p/plugins [p/error-handler-plugin p/request-cache-plugin pp/profile-plugin]})) ``` -------------------------------- ### Example GraphQL Queries Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc Illustrates example GraphQL queries for fetching user and repository data. The first query retrieves the creation date of a user, while the second fetches the creation date of a repository, specifying both owner and name. ```graphql query { user(login:"wilkerlucio") { createdAt } } ``` ```graphql query { repository(owner:"wilkerlucio" name:"pathom") { createdAt } } ``` -------------------------------- ### Pathom Basic Resolver and Parser Example (Clojure) Source: https://github.com/wilkerlucio/pathom/blob/main/docs/v2/pathom/2.2.0/introduction.html This Clojure code defines a basic Pathom setup with two resolvers: one to provide 'answer-to-everything' and another to calculate 'answer-plus-one'. It demonstrates how to register resolvers and create a parser instance. The example also shows how to call the parser with a simple query. ```clojure (ns com.wsscode.pathom.book.intro.demo (:require [com.wsscode.pathom.core :as p] [com.wsscode.pathom.connect :as pc])) (pc/defresolver answer [_ _] {::pc/output [:answer-to-everything]} {:answer-to-everything 42}) (pc/defresolver answer-plus-one [_ {:keys [answer-to-everything]}] {::pc/input #{:answer-to-everything} ::pc/output [:answer-plus-one]} {:answer-plus-one (inc answer-to-everything)}) (def registry [answer answer-plus-one]) (def parser (p/parser {::p/env {::p/reader [p/map-reader pc/reader2 pc/open-ident-reader p/env-placeholder-reader] ::p/placeholder-prefixes #{'>'}} ::p/mutate pc/mutate ::p/plugins [(pc/connect-plugin {::pc/register registry}) p/error-handler-plugin p/trace-plugin]})) (comment ; to call the parser and get some data out of it, run: (parser {} [:answer-to-everything])) ``` -------------------------------- ### Basic EQL Query Examples Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc Illustrates fundamental EQL (Enlive Query Language) query structures and their corresponding result formats. These examples demonstrate how to query simple attributes and nested data structures, serving as a basis for understanding Pathom's query processing. ```clojure ;; Query for a single attribute [:person/name] ;; Possible result {:person/name "Samantha"} ;; Query with nested data [:account/id {:billing/charges [:charge/amount]}] ;; Possible result {:account/id 1 :billing/charges [{:charge/amount 11} {:charge/amount 22}]} ``` -------------------------------- ### Pathom Query Notation Example Source: https://github.com/wilkerlucio/pathom/blob/main/docs/v2/pathom/2.2.0/core/getting-started.html Demonstrates Pathom's query notation for requesting specific data fields and nested structures from an entity. Queries are relative and resolved at runtime. ```clojure [:person/name :person/age] ``` ```clojure [:person/name {:person/address [:address/street]}] ``` -------------------------------- ### Initialize Pathom Connect Parser with Plugins Source: https://github.com/wilkerlucio/pathom/wiki/Connect Sets up the basic Pathom parser with essential plugins like `env-plugin` and `all-readers` for handling environment variables and map-based data resolution. This is the foundational step for any Pathom Connect application. ```clojure (ns pathom-docs.connect.getting-started (:require [com.wsscode.pathom.core :as p] [com.wsscode.pathom.connect :as p.connect])) (def parser (p/parser {::p/plugins [(p/env-plugin {::p/reader [p/map-reader p.connect/all-readers]})]})) (comment (parser {::p/entity {:hello "World"}} [:hello])) ``` -------------------------------- ### Setup Fulcro Card with Pathom Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.html Configures a Fulcro card for use in workspaces, defining its root component and an application started callback. The callback handles fetching data and loading the GraphqlDemo component, with error handling for index creation. It also sets up networking for the parser using pathom-remote and trace-remote. ```clojure (def graphql-demo (fp/factory GraphqlDemo)) ; setup the fulcro card to use in workspaces (ws/defcard graphql-demo (ct.fulcro/fulcro-card {::f.portal/root GraphqlDemo ::f.portal/app {:started-callback (fn [app] (go-catch (try ( parser (pfn/pathom-remote) (pfn/trace-remote))}})) ``` -------------------------------- ### Pathom Connect Mutations Setup Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc Sets up Pathom Connect with mutations, enabling features like auto-completion and integrating mutation results with the read engine. It requires `com.wsscode.pathom.core` and `com.wsscode.pathom.connect` libraries. The parser is configured for parallel execution and uses a connect plugin. ```clojure (ns com.wsscode.pathom.book.connect.mutations (:require [com.wsscode.pathom.core :as p] [com.wsscode.pathom.connect :as pc])) (pc/defmutation my-mutation [env params] ...) (def parser (p/parallel-parser {::p/env {::p/reader [p/map-reader pc/parallel-reader pc/open-ident-reader]} ::p/mutate pc/mutate-async ::p/plugins [(pc/connect-plugin {::pc/register send-message}) p/error-handler-plugin p/request-cache-plugin p/trace-plugin]})) ``` -------------------------------- ### Pathom Connect Input/Output Index Example (Clojure) Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc Shows a snippet of the index-io, which details the input and output schemas for resolvers. This index is used by Connect to understand the data flow and requirements of resolvers. ```clojure ::pc/index-io {#{} {:get-started/latest-product #:product{:id {} :title {} :price {}}} ``` -------------------------------- ### Fulcro Component Queries for GraphQL Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc Demonstrates how to define Fulcro components for querying a GraphQL API. It shows how namespaces in query keywords are handled and how the integration code strips them for GraphQL compatibility. The example includes a root component `TodoSimpleDemo` and a child component `TodoItem`. ```clojure (defsc TodoItem [this props] {:ident [:todo/id :todo/id] :query [:todo/id :todo/title :todo/completed]} ...) (defsc TodoSimpleDemo [this props] {:ident (fn [] [::root "singleton"]) :query [{:allTodoItems (fp/get-query TodoItem)}]}) ... ``` -------------------------------- ### Example Resolver Index Structure Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.html Provides a structural example of the `index-resolvers` map within Connect, showing how information about each resolver is stored, including its symbol, input, output, and resolution function. ```clojure { ::pc/index-resolvers { get-started/latest-product {::pc/sym get-started/latest-product ::pc/input #{} ::pc/output [{::get-started/latest-product [:product/id :product/title :product/price]}] ::pc/resolve (fn ...)} get-started/product-brand {::pc/sym get-started/product-brand ::pc/input #{:product/id} ::pc/output [:product/brand] ::pc/resolve (fn ...)} get-started/brand-id-from-name {::pc/sym get-started/brand-id-from-name ::pc/input #{:product/brand} ::pc/output [:product/brand-id] ::pc/resolve (fn ...)}} } ``` -------------------------------- ### Updating Parsing Environment in Pathom Joins Source: https://github.com/wilkerlucio/pathom/blob/main/docs-src/modules/ROOT/pages/core/getting-started.adoc Provides an example of how to modify the parsing environment during a join operation in Pathom by returning the `::p/env` key. ```clojure (letfn [(change-env [{:keys [env-data] :as env}] (assoc env ::p/env (assoc env-data :new-value 10)))] (p/parser (lc/path-map {:env-data {:change-env change-env}}) (p/env-defaults {:env-data {}}) (fn [x _] x))) ``` -------------------------------- ### Pathom Query Result Example Source: https://github.com/wilkerlucio/pathom/blob/main/docs/v2/pathom/2.2.0/core/getting-started.html Illustrates the expected map-based output format of a Pathom query, mirroring the structure of the query itself. Results are based on the requested fields and joins. ```clojure {:person/name "Sam" :person/age 32} ``` ```clojure {:person/name "Sam" :person/address {:address/street "111 Main St."}} ``` -------------------------------- ### Define GraphQL Connect Example in Clojure Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.html This code defines a complete GraphQL connect example, including required namespaces, resolvers, and mutations. It uses Pathom, Fulcro, and libraries to fetch and display data. It connects to a GitHub GraphQL API, allowing users to interact with repository data. ```clojure (ns com.wsscode.pathom.workspaces.graphql.github-demo (:require [com.wsscode.common.async-cljs :refer [go-promise let-chan "} ::p.http/driver p.http.fetch/request-async} ::p/mutate pc/mutate-async ::p/plugins [(pc/connect-plugin {::pc/register repositories ::pc/indexes indexes}) p/error-handler-plugin p/request-cache-plugin p/trace-plugin]})) (defonce github-index-status (go-promise ( user (select-keys [:user/name :user/email]) (merge {:user/id (random-uuid) :user/created-at (js/Date.)}))] (swap! db assoc-in [:users id] new-user) {:user/id id})) (pc/defresolver user-data [{::keys [db]} {:keys [user/id]}] {::pc/input #{:user/id} ::pc/output [:user/id :user/name :user/email :user/created-at]} (get-in @db [:users id])) (pc/defresolver all-users [{::keys [db]} _] {::pc/output [{:user/all [:user/id :user/name :user/email :user/created-at]}]} (vals (get @db :users))) (def api-registry [create-user user-data all-users]) (def parser (p/parallel-parser {::p/env {::p/reader [p/map-reader pc/parallel-reader pc/open-ident-reader] ::db (atom {})} ::p/mutate pc/mutate-async ::p/plugins [(pc/connect-plugin {::pc/register api-registry}) p/error-handler-plugin p/trace-plugin]})) [(user/create {:user/name "Rick Sanches" :user/email "rick@morty.com"}) [:user/id :user/name :user/created-at]] ``` -------------------------------- ### Complete GraphQL Connect Example with Resolver (Clojure) Source: https://github.com/wilkerlucio/pathom/blob/main/docs/v2/pathom/2.2.0/graphql/fulcro.html Provides a full example of setting up a Pathom GraphQL client with a custom resolver for fetching GitHub repositories. This demonstrates integrating Pathom Connect with GraphQL, local storage for tokens, and common Pathom plugins. ```clojure (ns com.wsscode.pathom.workspaces.graphql.github-demo (:require [com.wsscode.common.async-cljs :refer [go-promise let-chan [(::instruments {:sort :instrument/price})] ``` -------------------------------- ### Query with Sort Parameter Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc An example query demonstrating how to use the 'sort' parameter with the 'instruments-list' resolver to sort the results by instrument brand. ```clojure [(::instruments {:sort :instrument/brand})] ``` -------------------------------- ### Pathom Connect Parallel Reader Example Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc Provides example resolvers (`movie-details`, `movie-rating`, `movie-title-prefixed`) that illustrate the concept of `pc/parallel-reader`. This reader works with `parallel-parser` to detect dependencies, execute resolvers in parallel, and coordinate results, including handling secondary data paths. ```clojure (pc/defresolver movie-details [env input] { ::pc/input #{:movie/id} ::pc/output [:movie/id :movie/title :movie/release-date] } ...) (pc/defresolver movie-rating [env input] { ::pc/input #{:movie/id} ::pc/output [:movie/rating] } ...) (pc/defresolver movie-title-prefixed [env input] { ::pc/input #{:movie/title} ::pc/output [:movie/title-prefixed] } ...) ``` -------------------------------- ### Basic Async Parser Setup with Pathom Source: https://github.com/wilkerlucio/pathom/blob/main/docs/v2/pathom/2.2.0/core/async.html This snippet demonstrates how to set up and configure Pathom's async parser. It includes defining asynchronous and regular resolvers, and setting up the parser with essential plugins like the connect-plugin and trace-plugin. The async-reader2 is specified for handling core.async channels. ```clojure (ns com.wsscode.pathom.book.async.intro (:require [com.wsscode.pathom.core :as p] [cljs.core.async :as async :refer [go "}} ::p/mutate pc/mutate })) ``` -------------------------------- ### Pathom Query Notation for Joins Source: https://github.com/wilkerlucio/pathom/blob/main/docs-src/modules/ROOT/pages/core/getting-started.adoc Illustrates how to perform joins in Pathom queries to retrieve nested data, such as a person's name and their address details. ```clojure [:person/name {:person/address [:address/street]}] ``` -------------------------------- ### GraphQL User Query Example Source: https://github.com/wilkerlucio/pathom/blob/main/docs/v2/pathom/2.2.0/graphql/fulcro.html An example of a GraphQL query to retrieve user information, specifically the 'createdAt' field, given a user's login. This demonstrates how entry points are structured in GraphQL. ```graphql query { user(login:"wilkerlucio") { createdAt } } ``` -------------------------------- ### Basic EQL Query and Result Example (Clojure) Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.html Demonstrates a simple EQL query for a person's name and its corresponding result. This illustrates the basic input-output format of EQL queries processed by Pathom. ```clojure ;; query [:person/name] ;; possible result {:person/name "Samantha"} ``` -------------------------------- ### Pathom Query Notation for Scalar Values Source: https://github.com/wilkerlucio/pathom/blob/main/docs-src/modules/ROOT/pages/core/getting-started.adoc Demonstrates how to request a scalar value (like a name or age) using a simple keyword in a Pathom query. ```clojure [:person/name :person/age] ``` -------------------------------- ### Pathom Parser Initialization with Plugins Source: https://github.com/wilkerlucio/pathom/blob/main/docs/v2/pathom/2.2.0/core/plugins.html Demonstrates how to initialize a Pathom parser with a collection of plugins. Plugins are passed as a vector to the ::p/plugins option during parser creation. ```clojure (def parser (p/parser {::p/plugins [...]})) ``` -------------------------------- ### Use Idents for Single Input Queries Source: https://github.com/wilkerlucio/pathom/wiki/Connect This code illustrates how to use idents in Pathom to start queries from a single input, such as a product ID or a brand name. By using idents on the left side of a join, an initial context with a single attribute is provided, allowing for attribute discovery and the resolution of related data. ```clojure (parser {} [{[:product/id 1] [:product/brand]}]) ; => {[:product/id 1] #:product{:brand "Taylor"}} (parser {} [{[:product/brand "Taylor"] [:product/brand-id]}]) ; => {[:product/brand "Taylor"] #:product{:brand-id 44151}} ``` -------------------------------- ### Clojure Aliases for Pathom Namespaces Source: https://github.com/wilkerlucio/pathom/blob/main/docs/v2/pathom/2.2.0/introduction.html Defines common aliases for Pathom namespaces used in code examples. This setup assumes these requires are present in your environment for functions like `p/parser` or `::p/reader`. ```clojure (ns my-namespace (:require [com.wsscode.pathom.core :as p] [com.wsscode.pathom.connect :as pc] [com.wsscode.pathom.connect.graphql2 :as pcg] [com.wsscode.pathom.graphql :as pg] [com.wsscode.pathom.sugar :as ps] [com.wsscode.pathom.trace :as pt] ; clj only [com.wsscode.common.async-clj :refer [let-chan go-catch (merge {::demung identity} env) (update ::p/placeholder-prefixes #(or % #{})))))]})) ``` -------------------------------- ### Handling Union Queries with Pathom (Clojure) Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.html Demonstrates how to use Pathom's union queries to handle edges leading to heterogeneous nodes. The example shows how to specify a `:type` key on the entity to determine which subquery branch to follow for different data types like users, movies, and books. ```clojure (ns pathom-docs.entity-union (:require [com.wsscode.pathom.core :as p])) (def search-results [{:type :user :user/name "Jack Sparrow"} {:type :movie :movie/title "Ted" :movie/year 2012} {:type :book :book/title "The Joy of Clojure"}]) (def parser (p/parser {::p/plugins [(p/env-plugin {::p/reader [p/map-reader]})]})) (parser {::p/entity {:search search-results} ; here we set where pathom should look on the entity to determine the union path ::p/union-path :type} [{:search {:user [:user/name] :movie [:movie/title] :book [:book/title]}}]) ``` -------------------------------- ### Pathom Reader Function Signature Example Source: https://github.com/wilkerlucio/pathom/blob/main/docs/index.adoc Demonstrates how to access dispatch-key and params from the env in a Pathom reader function. Unlike om.next, Pathom's env contains these directly, simplifying reader implementation. ```clojure (get-in env [:ast :dispatch-key]) ; => dispatch-key (get-in env [:ast :params]) ; => params ``` -------------------------------- ### Pathom Connect Boilerplate Setup in Clojure Source: https://github.com/wilkerlucio/pathom/blob/main/docs-src/modules/ROOT/pages/connect/basics.adoc This code snippet demonstrates the baseline boilerplate for setting up a Pathom Connect-based query processing system in Clojure. It includes defining resolvers using `pc/defresolver`, composing them into a registry, and creating a parser using `p/parser` with the connect plugin. ```clojure (ns com.wsscode.pathom.book.connect.getting-started (:require [com.wsscode.pathom.core :as p] [com.wsscode.pathom.connect :as pc])) ;; Define one or more resolvers (pc/defresolver some-symbol [env input] ...) (pc/defresolver some-other-symbol [env input] ...) ... ;; resolvers are just maps, we can compose many using sequences (def my-app-registry [some-symbol some-other-symbol]) ;; Create a parser that uses the resolvers: (def parser (p/parser {::p/env {::p/reader [p/map-reader pc/reader2 pc/open-ident-reader p/env-placeholder-reader] ::p/placeholder-prefixes #{'>'}} ::p/mutate pc/mutate ::p/plugins [(pc/connect-plugin {::pc/register my-app-registry}) ; setup connect and use our resolvers p/error-handler-plugin p/trace-plugin]})) ```