Injecting ResolversΒΆ

Schemas start as EDN files, which has the advantage that symbols do not have to be quoted (useful when using the list and non-null qualifiers on types). However, EDN is data, not code, which makes it nonsensical to define field resolvers directly in the schema file.

One option is to use assoc-in to attach resolvers after reading the EDN, but before invoking com.walmartlabs.lacinia.schema/compile. This can become quite cumbersome in practice.

Instead, the standard approach is use com.walmartlabs.lacinia.util/inject-resolvers, [1] which is a concise way of matching fields to resolvers, adding the :resolve key to the nested field definitions.

(ns org.example.schema
  (:require
    [clojure.edn :as edn]
    [clojure.java.io :as io]
    [com.walmartlabs.lacinia.schema :as schema]
    [com.walmartlabs.lacinia.util :as util]
    [org.example.db :as db]))

(defn star-wars-schema
  []
  (-> (io/resource "star-wars-schema.edn")
      slurp
      edn/read-string
      (util/inject-resolvers {:Query/hero db/resolve-hero
                              :Query/human db/resolve-human
                              :Query/droid db/resolve-droid
                              :Human/friends db/resolve-friends
                              :Droid/friends db/resolve-friends})
      schema/compile))

The keys in the map passed to inject-resolvers use the namespace to define the object (such as Human or Query) and the local name to define the field within the object (hero and so forth).

The inject-resolvers step occurs before the schema is compiled.

[1]An older approach is still supported, via the function com.walmartlabs.lacinia.util/attach-resolvers, but inject-resolvers is preferred, as it is simpler.