Using Clojure Spec with Datomic entities
Asked Answered
L

1

9

Say I have the following specs:

(s/def :person/age number?)
(s/def :person/name string?)

(s/def ::person (s/keys :req [:person/name :person/age]))

Then I fetch an entity from Datomic:

(def person-entity (d/entity (d/db conn) [:person/name "Mr entity"]))

If I try to check conformance with the spec it fails because entities are not maps:

(s/explain ::person person-entity)

val: #:db{:id 17592186069950} fails spec: :some-ns/person predicate: map?

My app has functions that take entities as arguments and would like to avoid having to reify entities to maps everywhere just to get spec instrumentation to work in development.

How should I go about validating entities through spec?

Latona answered 11/10, 2016 at 6:44 Comment(2)
Good question. After you find a solution to this problem, won't you also run into an issue with namespaces? The entity map will be something like: {:person/name "Mr. Entity"}, which does not validate against (s/keys :req [::name ::age]) unless those definitions happen to be in (ns person). But that forces you to define a bunch of top level package namespaces, which doesn't seem reasonable.Manhour
Thanks @Marc, I've updated the example.Latona
T
3

Although it is true that your namespaces are a bit off (you should be using :person/name instead of ::name), there is also a restriction in spec that could be lifted. Currently s/keys requires that all input collections conform to the clojure.core/keys predicate. Datomic entities are not maps, and so do not pass that check (and hence the error about the map? predicate).

I've filed a bug report here: http://dev.clojure.org/jira/browse/CLJ-2041 Feel free to upvote/follow the ticket if you wish.

Tammara answered 11/10, 2016 at 18:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.