This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-12-01
Channels
- # adventofcode (11)
- # aws (8)
- # beginners (70)
- # boot (2)
- # cider (9)
- # cljs-dev (29)
- # cljsrn (2)
- # clojure (67)
- # clojure-android (2)
- # clojure-dusseldorf (5)
- # clojure-greece (12)
- # clojure-italy (4)
- # clojure-nl (3)
- # clojure-poland (3)
- # clojure-russia (5)
- # clojure-spec (80)
- # clojure-uk (9)
- # clojurescript (73)
- # core-async (17)
- # cursive (1)
- # data-science (5)
- # datomic (29)
- # emacs (5)
- # fulcro (257)
- # graphql (2)
- # hoplon (2)
- # jobs (2)
- # klipse (3)
- # leiningen (9)
- # lumo (4)
- # nyc (1)
- # off-topic (48)
- # om (7)
- # other-languages (11)
- # pedestal (4)
- # re-frame (18)
- # remote-jobs (1)
- # rum (10)
- # shadow-cljs (5)
- # spacemacs (20)
- # sql (5)
- # test-check (44)
- # unrepl (8)
- # yada (9)
Hi, has anybody successfully used spec for web validation and translated the validation failures to HTTP 400 for nested data models? Any example or references would be great to have.
Don’t know about success, but there are routing libs like compojure-api and reitit, which support spec as web (backend) validation. There is an example in https://github.com/metosin/c2. For invalid input, produces http 400 with this kind of body:
{
"spec": "(spec-tools.core/spec {:spec (clojure.spec.alpha/keys :req-un [:c2.spec/x :c2.spec/y]), :type :map, :keys #{:y :x}, :keys/req #{:y :x}})",
"problems": [
{
"path": [
"y"
],
"pred": "clojure.core/int?",
"val": "a",
"via": [
"c2.spec/y"
],
"in": [
"y"
]
}
],
"type": "compojure.api.exception/request-validation",
"coercion": "spec",
"value": {
"x": 100,
"y": "a"
},
"in": [
"request",
"body-params"
]
}
so, just the :problems
polished so that it can be serialized:
https://github.com/metosin/reitit/blob/master/modules/reitit-spec/src/reitit/ring/coercion/spec.cljc#L84-L87
I was looking at https://github.com/metosin/spec-tools meanwhile and thought of pinging you!
We are using a different data-driven router, so looking for a standalone validation mechanism using spec. Is there any such library?
Well, reitit is kinda modular, if you take the metosin/reitit-spec
is’s flattened deps tree is: spec-tools, clojure.spec & meta-merge
it bring the ring-module but it has no dependencies. Could move the Coercion protocols into own module.
do you think the coercion should be totally out of reitit (modules)? I would be more polite towards other routing libs at least.
Thanks, let me try out Reitit-spec. I’m sort of new to spec. And yes, compat with other routing libs would be very useful.
Though can’t comment now about code organization.
there is already compat, but needing to include another routing lib to get coercion for another is kinda odd. Plan is to ship coercion interceptors too (as they don’t require any new deps), so they should be usable from “pedestal-style interceptor web libs”
I am using Ring with a routing lib, but right now just using plain app code to do validation (it’ a new project) - no m/w for now.
ok, I think I removed the “vanilla ring coercion middleware” in favour of the reitit “compiled” one (much faster). Could push them back to support other routing libs. This: https://github.com/metosin/reitit/commit/7979c9de9d42afd611e13da40502ac8ea1c0c0e3
I think I can form an opinion about the commit after some more experience with spec.
I’m looking at https://metosin.github.io/reitit/ — is there a section that describes reitit-spec in particular?
I could cook up examples of that with plain ring. Most likely have time on the weekend.
Thanks! Looking into it. More examples would be cool for sure.
How would I define keys and sharing them between specs? like `(def base [::id ::something]) (s/keys :req base)`
I suppose it fails because of compile-time evaluation
s/merge
?
https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html#clojure.spec.alpha/merge
You can define a base spec and merge that into others
@andre.stylianos Thank you, that seems to be exactly what I am looking for
from what @andreas862 asked, he wants to be able to combine specs, not necessary merge them
I don’t think I would agree with that
This is exactly when you want to merge
gen and conform
in that conform doesn’t flow
gen is the big one though
Just adding that what I wanted was to merge even if my wording was a bit unclear
(s/def ::a string?)
(s/def ::b (s/and (s/conformer str/upper-case) string?))
(s/conform
(s/merge
(s/keys :req-un [::a])
(s/keys :req-un [::b]))
{:a "kikka", :b "kukka"})
; => {:a "kikka", :b "KUKKA"}
(s/conform
(s/merge
(s/keys :req-un [::b])
(s/keys :req-un [::a]))
{:a "kikka", :b "kukka"})
; => {:a "kikka", :b "kukka"}
speaking of schema-related transformations, I've been experimenting with reviving the stuff in https://github.com/gfredericks/schema-bijections as a library that only deals with bijections, not referring directly to schema/spec at all I'm curious how useful something like that would be for transforming data to the format that a spec expects (and back? e.g. jdbc)
I think generating bijections from specs would be the ideal result
I still have to decide if/how to incorporate surjections though
since those are also useful in some cases
tbh I didn't really like the form it took in schema, but that was practical. I am not sure I have seen a solution I like for these kind of transformations yet
the form what took in schema?
oh right -- I don't like them because they represent surjections everywhere, even for uses when bijections can work and it makes it easy to test your function-that-coerces-its-inputs with the canonical form of the data, since that's easier, and never actually test the production form that has to be coerced
bijections from specs would be awesome ➕
I am envisioning that you can define different styles for other representations, like json and jdbc, and then get bidirectional functions for converting your canonical spec form from one to the other
e.g., "I want camel-cased keys, I want date-times serialized like this" etc.
that category of things, but hopefully arbitrarily flexible
so if you say your json representation has camelCased keys while your internal representation is kebab-cased, then a json input with kebab-cased keys would be considered incorrect and cause an exception rather than just silently be accepted
There was a hint of a next iteration of spec coming out at some point (I think in Rich's talk), I am wondering if there are changes related to these kind of things (and others often mentioned).
I personally am curious to see how spec forms conforming (or whatever replaces it) will take form
oh yeah, I forgot about that
you mean enabling specs to have metadata attached?
I assume they already can so you must mean something else
@alexmiller related to the s/merge
problem, there is a PR request in spec-tools of a merge that seems to fix the problem. Could that be pushed to Spec itself? Comments welcome: https://github.com/metosin/spec-tools/pull/91
fixes what problem?
e.g. merge merges that values, so the unconformed value override the conformed ones.
it doesn’t override, it’s just that only the last spec in the merge controls the conformed result
that is the intent, not a bug, but it can have some non-obvious effects, particularly with unqualified keys
I think there is a ticket for this already in jira, but not sure what should be done with it
I wouldn’t re-open that, but if there is a good statement of a problem and a patch, we can take a look at it
that is, in a new ticket
I have no idea what that PR is doing at a glance
Rich has a pretty extensive re-work coming for spec (post 1.9 release) and I suspect we won’t really look at any fixes till we’re on the other side of that
Ah interesting! What kind of rework? Is it on the implementation side or is there going to be some kind of change to the interface?