Indexes
To make efficient lookups, Pathom uses a series of indexes generated from the user resolvers.
index-oir
This is the most important index to understand how Pathom processes the data.
oir
stands for output
→ input
→ resolver
.
In other words, this is the index that tells Pathom which are the paths available to reach a given attribute in the system.
Let's look at an example and talk over it:
; for this resolver
(pco/defresolver product-by-id [{:keys [acme.product/id]}]
{::pco/input [:acme.product/id]
::pco/output [:acme.product/name
:acme.product/price
:acme.product/in-stock?]}
(fetch-product id))
; we get this index-oir
{:com.wsscode.pathom3.connect.indexes/index-oir
{:acme.product/name {{:acme.product/id {}} #{product-by-id}}
:acme.product/price {{:acme.product/id {}} #{product-by-id}}
:acme.product/in-stock? {{:acme.product/id {}} #{product-by-id}}}}
With this index, Pathom can ask: How can I fetch :acme.product/price
in the system?
For which the answer is:
{{:acme.product/id {}} #{product-by-id}}
Or in plain english: The index says you can fetch the product price, given you provide some
product id, using the edge product-by-id
.
The input in this index uses the shape descriptor format.
This is an overview of this index, for more details on how the planner uses it, check the planner page.
index-io
This index tells, for given attribute set (with empty, one or more items), which attributes are directly reachable (one resolver distance) from that set.
io
stands for input
→ output
.
Here is what index-io
looks like, using the same resolver from our previous example:
{:com.wsscode.pathom3.connect.indexes/index-io
{#{:acme.product/id}
{:acme.product/name {}
:acme.product/price {}
:acme.product/in-stock? {}}}}
The output
part uses the shape descriptor format.
Smart maps use this index to figure reachable attributes when used in "reachable mode".
This is a good index to create auto-complete features in editors for Pathom integration.
index-attributes
This index contains accumulated information about how a specific attribute relates to other attributes and resolvers.
Let's use the full-name
resolver example to demonstrate the index-attributes at play:
(pco/defresolver full-name [{::keys [first-name last-name]}]
{::full-name (str first-name " " last-name)})
{:com.wsscode.pathom3.connect.indexes/index-attributes
{#{::first-name ::last-name} {:com.wsscode.pathom3.connect.indexes/attr-id #{::first-name ::last-name}
:com.wsscode.pathom3.connect.indexes/attr-provides {::full-name #{:full-name}}
:com.wsscode.pathom3.connect.indexes/attr-input-in #{full-name}}
::first-name {:com.wsscode.pathom3.connect.indexes/attr-id ::first-name
:com.wsscode.pathom3.connect.indexes/attr-combinations #{#{::first-name ::last-name}}
:com.wsscode.pathom3.connect.indexes/attr-input-in #{full-name}}
::last-name {:com.wsscode.pathom3.connect.indexes/attr-id ::last-name
:com.wsscode.pathom3.connect.indexes/attr-combinations #{#{::first-name ::last-name}}
:com.wsscode.pathom3.connect.indexes/attr-input-in #{full-name}}
::full-name {:com.wsscode.pathom3.connect.indexes/attr-id ::full-name
:com.wsscode.pathom3.connect.indexes/attr-reach-via {#{::first-name ::last-name} #{full-name}}
:com.wsscode.pathom3.connect.indexes/attr-output-in #{full-name}}}}
The first level of the index is the attribute itself, the details we can explain key by key:
:com.wsscode.pathom3.connect.indexes/attr-id
Contains the ID of the attribute, it may be a keyword (as seen in the example) or also a set in cases of attribute combinations.
:com.wsscode.pathom3.connect.indexes/attr-input-in
A set containing a list of all resolvers in which this attribute appears as an input.
:com.wsscode.pathom3.connect.indexes/attr-output-in
A set containing a list of all resolvers in which this attribute appears as an output.
:com.wsscode.pathom3.connect.indexes/attr-provides
This is a sub-index, telling what other attributes are reachable from this attribute, by which resolver.
:com.wsscode.pathom3.connect.indexes/attr-reach-via
This is a sub-index, telling what other attributes you can use to reach the current, by which resolver.
:com.wsscode.pathom3.connect.indexes/attr-combinations
A set with all the input combinations that this attribute appears in.
index-resolvers
In this index, you can look up resolvers by their name. Using both product-by-id
and
full-name
resolvers, this is what the index-resolvers
looks like:
{:com.wsscode.pathom3.connect.indexes/index-resolvers
{product-by-id
#com.wsscode.pathom3.connect.operation.Resolver
{:config {:com.wsscode.pathom3.connect.operation/input [:acme.product/id]
:com.wsscode.pathom3.connect.operation/requires {:acme.product/id {}}
:com.wsscode.pathom3.connect.operation/output [:acme.product/name :acme.product/price :acme.product/in-stock?]
:com.wsscode.pathom3.connect.operation/provides {:acme.product/name {}
:acme.product/price {}
:acme.product/in-stock? {}}
:com.wsscode.pathom3.connect.operation/op-name product-by-id}
:resolve product-by-id--23075}
full-name
#com.wsscode.pathom3.connect.operation.Resolver
{:config {:com.wsscode.pathom3.connect.operation/input [::first-name ::last-name]
:com.wsscode.pathom3.connect.operation/requires {::first-name {} ::last-name {}}
:com.wsscode.pathom3.connect.operation/output [::full-name]
:com.wsscode.pathom3.connect.operation/provides {::full-name {}}
:com.wsscode.pathom3.connect.operation/op-name full-name}
:resolve full-name--23079}}}
index-mutations
In this index, you can look up mutations by their name. Here is an example of what it looks like:
;; the mutations
(pco/defmutation create-product [{:keys [acme.product/name acme.product/price acme.product/in-stock?]}]
{::pco/output [:acme.product/id]}
(create-product name price in-stock?))
{:com.wsscode.pathom3.connect.indexes/index-mutations
{demos.async-mutations/create-product
{:config
{:com.wsscode.pathom3.connect.operation/provides
{:acme.product/id {}},
:com.wsscode.pathom3.connect.operation/params
[:acme.product/name :acme.product/price :acme.product/in-stock?],
:com.wsscode.pathom3.connect.operation/output [:acme.product/id],
:com.wsscode.pathom3.connect.operation/op-name
demos.async-mutations/create-product},
:mutate
#object[demos.async_mutations$create_product__19314 0x2e4c1d84 "demos.async_mutations$create_product__19314@2e4c1d84"]}},}