Defining Specs

Specs are logical compositions of predicates (functions returning a logical true/false value) used to describe a set of data values. The spec library provides operations to create, combine, and register specs.

To work with spec, you’ll need to load the namespace clojure.spec.alpha, which is commonly aliased to s. All spec examples in this chapter use the s alias to refer to functions or macros from the clojure.spec library.

 (require '[clojure.spec.alpha :as s])

The s/def macro names and registers a spec in the global registry of specs accessible in the current Clojure program. The syntax for s/def is:

 (s/def name spec)

Spec names are qualified keywords. For example, a simple spec definition using a predicate spec looks like:

 (s/def :my.app/company-name string?)

Place this spec definition in your Clojure source file at the top level, just like var definitions made with the special form def. When creating function specs, most developers place them before the function they describe or sometimes collect all of the function specs into a separate namespace. For example, clojure.core itself has specs in a separate namespace clojure.core.specs.alpha.

At runtime, specs are read and evaluated like function definitions. The global spec registry stores the spec, keyed by name.

Spec names must be fully qualified keywords. As a Clojure developer, it’s your responsibility to use sufficiently qualified keywords as names so that your code will work with other code in the greater ecosystem. If you’re writing a library for public reuse, you should follow rules similar to those used when choosing the project group ID and artifact ID when deploying the project artifact. Namely, the qualified part of the keyword should start with a domain name or a product or project name for which you control the trademark or mindshare in the market. For example, :cognitect.transit.handler/name would be sufficient.

When these qualified keywords are cumbersome in code, we can use aliases and auto-resolved keywords to simplify their names. Auto-resolved keywords start with ::. If no qualifier is specified (::ingredient), then the current namespace is used as the qualifier. Since project namespaces are often sufficiently qualified, this is a great way to piggieback on good choices we’ve already made.

If a qualifier is specified, then it can refer to an alias defined in the current namespace. For example, ::recipe/ingredient might expand to the namespace aliased to recipe, perhaps :cookingco.recipe/ingredient. In this chapter, we often use auto-resolved keywords for brevity in the code examples.

Next, we’ll look at how to create and combine specs to validate data, which we can choose to do during development or even at runtime.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.136.18.141