expose-api
is a Clojure library designed to simplify the process of creating public-facing API namespaces. In Clojure, it's common to define a namespace as your "public" interface and have implementation namespaces with the actual code. Manually writing the public namespace can be tedious. This library automates that process by generating a Clojure namespace that wraps implementation vars and exposes a public API.
Add the following dependency to your project.clj
:
[com.xadecimal/expose-api "0.3.0"]
Add the following dependency to your deps.edn
:
{:deps {com.xadecimal/expose-api {:mvn/version "0.3.0"}}}
Here's a quick example of how to use expose-api
to generate a public API namespace:
(ns your.namespace
(:require [com.xadecimal.expose-api :as api]))
(api/expose-api
:file-path "./src/com/xadecimal/my_lib.clj"
:ns-code `(~'ns ~'com.xadecimal.my-lib
"A very cool library which lets you do cool things.
To use it, require it and call its cool functions."
(:refer-clojure :exclude ~'[defn])
(:require ~'[com.xadecimal.my-lib.impl :as impl]))
:vars [#'impl/defn #'impl/cool])
This will create a file ./src/com/xadecimal/my_lib.clj
containing Clojure source code of the specified namespace form, and with a function named cool
which calls the impl/cool
function, with the same doc and arities as that of the impl/cool
function, as well as a macro named defn
which calls the impl/defn
macro, with the same doc and arities as that of the impl/defn
macro.
file-path
- A string pointing to the path where you want the generated .clj
namespace source file to be created. This should match the ns-code
namespace path. It's relative to where you are executing from.ns-code
- An ns
code form, which will become the ns
directive in the generated namespace source code. Ensure that you require the implementation namespaces that the vars use.vars
- A sequence of vars that you want to wrap and expose publicly in the generated namespace. Vars are assumed to come from implementation namespaces.Potemkin's import-vars
is another tool that facilitates the creation of public APIs by importing vars from other namespaces. Here's a comparison of expose-api
and Potemkin's import-vars
:
import-vars
is used directly in the namespace definition to import vars from other namespaces.(ns your.namespace
(:require [potemkin :refer [import-vars]]
[some.other.namespace :as other]))
(import-vars other/foo other/bar)
expose-api
generates a new namespace file with the specified public API, wrapping implementation vars.(api/expose-api
:file-path "./src/com/xadecimal/my_lib.clj"
:ns-code `(~'ns ~'com.xadecimal.my-lib
"A very cool library which lets you do cool things."
(:refer-clojure :exclude ~'[defn])
(:require ~'[com.xadecimal.my-lib.impl :as impl]))
:vars [#'impl/defn #'impl/cool])
It is recommended to use expose-api
from a build step. Here’s an example of how you can add such a build step using tools.build
:
Create a build script (e.g., build.clj
):
(ns build
(:require [clojure.tools.build.api :as b]
[com.xadecimal.expose-api :as api]))
(defn generate-api [m]
(api/expose-api
:file-path "./src/com/xadecimal/my_lib.clj"
:ns-code `(~'ns ~'com.xadecimal.my-lib
"A very cool library which lets you do cool things."
(:refer-clojure :exclude ~'[defn])
(:require ~'[com.xadecimal.my-lib.impl :as impl]))
:vars [#'impl/defn #'impl/cool]))
Add a build alias to your deps.edn
:build {:extra-deps {io.github.clojure/tools.build {:git/tag "v0.10.4" :git/sha "31388ff"}}
:extra-paths ["."]
:ns-default build}
You need it to include your project's source whose vars are getting exposed. This is why we use :extra-deps
and :extra-paths
, because we will run it with -X
and not as a tool.
Run the build script:
clojure -X:build generate-api
This will generate the specified public API namespace as part of your build process, ensuring that your API is always up to date with the latest implementation changes.
This project is licensed under the MIT License - see the LICENSE file for details.
Thanks to the Clojure community for their support and contributions to the ecosystem.
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close