[spec] Support for selective conforming with clojure.spec

Description

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* and clojure.spec/conform, both taking a extra user-provided callback/visitor function. If the callback is provided, it's called from within the Specs conform* with the current spec as argument and it will return either nil 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-arity conform and add implementations for it on all current specs. Currently this is not possible.

[1] https://github.com/metosin/spec-tools

Environment

[org.clojure/clojure "1.9.0-alpha14"]

Attachments

1

Activity

Show:

Alex Miller July 11, 2018 at 12:22 AM

We won’t look at this at least until we do the next batch of implementation changes. I continue to think we will most likely decline this.

import July 10, 2018 at 11:11 PM

Comment made by: marco.m

Hello, any news ?

Tommi Tommi October 31, 2017 at 6:05 PM

Tommi Tommi October 4, 2017 at 7:02 AM

Any news on this?

Tommi Tommi July 22, 2017 at 8:12 AM

initial work as patch.

Details

Assignee

Reporter

Labels

Priority

Affects versions

Created February 22, 2017 at 8:11 PM
Updated August 24, 2023 at 7:02 AM