Liking cljdoc? Tell your friends :D

Discovery

Init provides multiple flavors of building configurations.

Namespaces

You can create a config map from one or more namespaces with annotated vars:

(require '[my-project.components])
(require '[init.discovery :as discovery])

(def config (discovery/from-namespaces [*ns* (the-ns ('my-project.components)]))

Instead of enumerating namespaces manually, you can also specify all namespaces with a given prefix:

(def config (discovery/from-namespaces (discovery/find-namespaces ['my.project])))

Binding

Hand-pick vars to use as components:

(def config (discovery/bind {:app/config  #'config/load-config
                             :http/server #'web/start-server}))

These vars do not need to be annotated if:

  • They have non-function values, i.e. are defined with def
  • They are nullary (zero argument) functions

Functions that take arguments will need :init/inject metadata, so that init can determine which dependencies to supply as arguments when starting the component.

Classpath scanning

Finds namespaces on the classpath matching prefixes:

(def config (discovery/scan '[my-app my-team.lib]))

Static scanning

There is a utility to scan the classpath at compile time:

(def config (discovery/static-scan '[my-app my-team.lib]))

This allows for skipping classpath scanning at runtime and ahead-of-time compilation of matching namespaces.

Service Loader

Init supports registration of namespaces via a mechanism similar to java.util.ServiceLoader, using the same file format and location: It will look for files named META-INF/services/init.namespaces on the classpath.

Example init.namespaces file, note the empty lines and comment:

my-company.config
my-company.server

# Ring handlers
my-company.handlers.api
my-company.handlers.ui

To load all of these namespaces:

(def config (discovery/services))

This requires com.fbeyer.autoload on the classpath.

Mix and match

Most discovery functions accept an existing config as first argument, so that you can freely combine them:

(def config (-> (discovery/scan ['my-app.handlers])
                (discovery/bind {:http/server #'server/run-server}
                (discovery/from-namespace [*ns*]))))

Since configurations are just maps, you can easily transform and filter them:

(require '[init.component :as component])

(def config (->> (discovery/scan ['my-app])
                 (filter #(component/provides? (val %) :profile/production)
                 (into {}))))

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close