Details
Assignee
UnassignedUnassignedReporter
Tommi TommiTommi TommiLabels
Priority
MajorAffects versions
Details
Details
Assignee
Unassigned
UnassignedReporter
Tommi Tommi
Tommi TommiLabels
Priority

Affects versions
Created February 22, 2017 at 8:11 PM
Updated August 24, 2023 at 7:02 AM
Problem
using
clojure.spec
in runtime border validation supporting multiple exchange formats is hard.Details
Currently in clojure.spec (alpha-14), conformers are attached to Spec instances at creation time and they are invoked on every conform. This is not very useful in system border validation, where conforming/coercion functions should be selected based on runtime data, e.g. the exchange format.
Examples:
a
keyword?
spec:with EDN, no coercion should be done (it can present Keywords)
with JSON, String->Keyword coercion should be applied
with String-based formats (CSV, query-params, ...), String->Keyword coercion should be applied
a
integer?
spec:with EDN, no coercion should be done (it can present numbers)
with JSON, no coercion should be done (it can present numbers)
with String-based formats (CSV, query-params, ...), String->Long coercion should be applied
Here is a more complete example:
To use this today, one needs to manually create new border specs with different conformers for all different exchange formats. Non-qualified keywords could be mapped in
s/keys
to work (e.g.::title
=>::title$JSON
), but this wont work if fully qualified keys are exposed over the border (like::id
in the example) - one can't register multiple, differently conforming version of the spec with same name.Suggestion
Support selective conforming in the Spec Protocol with a new 3-arity
conform*
andclojure.spec/conform
, both taking a extra user-provided callback/visitor function. If the callback is provided, it's called from within the Specsconform*
with the current spec as argument and it will return eithernil
or a 2-arity conformer function that should be used for the actual confrom.Actual conforming-matcher implementations can be maintained in 3rd party libraries, like spec-tools[1].
Using it would look like this:
Alternative
Another option to support this would be to allow Specs to be extended with Protocols. 3rd party libs could have a new
Conforming
protocol with 3-arityconform
and add implementations for it on all current specs. Currently this is not possible.[1] https://github.com/metosin/spec-tools