Fork me on GitHub

@tbaldridge you are doing json schema? here too. I think there are ~4 people doing the same now. Should we do join efforts somehow?

Yehonathan Sharvit11:03:35

Is it a good idea to use spec for validating data before inserting it into a mongodb document?

Yehonathan Sharvit11:03:17

The problem I have is that spec is “open” and we have been told by Rich that it is a bad idea to have “closed” specs

Yehonathan Sharvit11:03:55

But I need to make sure I catch typo errors like fristname instead of firstname


if your firstname key is required spec will still catch it as a missing required key

Yehonathan Sharvit11:03:06

Yes but in my case it’s an optional key


@viebel What's the behavior you're looking for?

Yehonathan Sharvit12:03:31

I’d like s/valid? ::my-spec to fails for {:fristname “Jo” :age 10} but to succeed for {:firstname “Jo” :age 10}

Yehonathan Sharvit12:03:27

(s/def ::my-spec (s/keys :opt-un [::firstname ::age])) will not catch this error


Maybe roll your own using clojure.core/keys

Yehonathan Sharvit12:03:37

My question is not technical but philosophical

Yehonathan Sharvit12:03:06

I mean: is it good practice to forbid keys?

Yehonathan Sharvit12:03:33

In a lot of occasions Rich and @alexmiller recalls us that specs should be "open"


Forbidding keys will inhibit forward compatibility, mixing keys e.g for metadata etc.


In your case, I would at least select-keys and dissoc nils before persisting data.


You can catch invalid keys without writing the exclusion into the spec

Yehonathan Sharvit12:03:30

(In my case it’s a deeply nested map)


You can write code, admittedly more challenging with nesting


@alexmiller hey heads up, i think there's a typo in the blog post (s/conform (s/and int? even? #(> % 1000)) 1111) evals to :clojure.spec/invalid, not 1111


@devth indeed, although that should have just been an even number


@viebel If you write a closed keys predicate for each parent key and combine with s/keys, it will drill down the nested map. (s/and (s/keys ...) your-closed-keys-pred?)


bit of a newbie question about spec... i'm currently using gen/generator to generate some maps with UUIDs. i'd then like to generate another set of maps that will contain vectors of those UUIDs. i can generate both sets of maps and then assoc the UUIDs from one set to the other but i'm wondering if there's a better workflow for this?


Like {:a #uuid "sth", :b #uuid "sth-else"} and {:sths [#uuid "sth", #uuid "sth-else"]}?


yes, i think so. my example is a collection of "items" with UUIDs {:type :item :uuid #someuuid} and then another spec for a "package" containing random items {:type :package :contents [#someuuid #someotheruuid]}


i'm no expert but I'd just write a function for that transformation


and have specs for both data structures


yes, i have specs for both data structures. after generating samples of both i can just reassoc contents from one collection to the other


i was using this blog post as an example but i'm not sure i understand gen/fmap


gen/fmap lets you transform the value that a generator generates


so e.g., if you have a generator integers g, then (gen/fmap str g) is a generator of stringified integers


I have been remiss in not mentioning that I will be doing clojure.spec training before the Conj in Portland March 29th - you can register independently from Clojure/west (although why would you want to?)


Is there something like s/multi-spec that doesn't use the extra machinery of a multimethod that would be more appropriate for a situations where the cases are a closed set? I don't need to be able to extend the list of cases easily.


I could use s/or, but that doesn't dispatch by looking at the value being conformed


which maybe is fine?


It seems like dispatching on a tag would be faster in general when it's an option, but since it's a small, close set of variants, maybe it just doesn't matter much


just use multi-spec


you can put ^:private on your multimethod if you want


that’ll keep it closed


@peeja It depends on what's bothering you with the multi-spec solution. You can't do much about the style. The set of options is kinda closed and you'll get a "no method" exception on unknown dispatch values. In addition you could define a spec for the dispatch key using a set #{...} to get a nicer explanation for invalid values.


It's not so much that I need to enforce that it's closed (I do have a spec on the key) as much as a multi-method is grammatically pretty heavy and I don't need the advantages it offers. Having written it out, though, the s/or actually works pretty well for me here.


i do think a syntactic shortcut for the common case of single-keyword dispatch may be warranted


it’s really not too bad tho