Fork me on GitHub
#polylith
<
2023-06-28
>
Samuel Ludwig16:06:38

There's been a few discussions in the channel mentioning specs+where to put them I notice in the realworld example-app (https://github.com/furkan3ayraktar/clojure-polylith-realworld-example-app/blob/master/components/article/src/clojure/realworld/article/interface/spec.clj) that specs are provided by an interface (per-component), and are all defined as being under the :core/ namespace (while keeping all keys in map-specs unqualified) Is this still a typical approach for those building polylith projects in production? Any other approaches that have worked for you?

seancorfield18:06:19

There's no One True Way ™️ with Specs. You can put them where they best work for you. I blogged about how we used Spec pre-Polylith and very little has changed for us: https://corfield.org/blog/2019/09/13/using-spec/ Sometimes it's easier to have the Specs in a subinterface -- <top-ns>.<component>.interface.specs -- depending on where they need to be used from. Sometimes they'll be in the regular .interface, sometimes in a .impl.

Samuel Ludwig19:06:16

I have read this post before 😄, and so interesting: sounds like you still have your specs largely defined in the namespace where the core functionality for those data-structures is implemented? That is how I'd done things prior. I'm assuming then that you expose the specs in the interface like you'd do the functionality then? in <top-ns>.<component>.interface you have definitions like

(ns <top-ns>.user.interface
  (:require [<top-ns>.user.core :as core]
            [<...>.spec :as s]))

...
(s/def ::user ::core/user)
...
?

seancorfield19:06:59

If those specs are needed by both that component's implementation and by other components, it's easier to use <top-ns>.<component>.interface.specs as noted above.

seancorfield19:06:21

(since otherwise you might want your .impl to require your .interface which would be circular)

Samuel Ludwig19:06:02

right right, so you would consider it desirable that the specs are namespaced as :<top-ns>.<component>.interface.specs/<spec-name> then? (i personally think this makes sense/feels consistent, just confirming)

seancorfield19:06:46

It depends on the intended scope, like any qualified names.

seancorfield19:06:53

We tend to only use ::spec-name when those specs are not externally used. Otherwise we use a specific prefix that indicates their scope (at the domain level).

seancorfield19:06:22

Or if the risk of conflict with other specs is high and using the full ns is the only way to guarantee uniqueness.

seancorfield19:06:43

e.g., we have a bunch of :wsbilling/<spec> names that are defined in a few different parts of our overall ws.billing*.*namespace tree (part-base, part-components).

Samuel Ludwig19:06:46

ahhh, thats very interesting to hear; I appreciate the feedback/info, this is useful meditation material