内容简介:Last week I took a look at three data specification libariers in Clojure:Data specification language.This is the foundation of every data specification library: a way to describe the data with a schema. You could use an existing language such asValidation.
Last week I took a look at three data specification libariers in Clojure: Schema, Spec, and Malli . This week, let’s talk about the essential features of these libraries.
Data specification language.This is the foundation of every data specification library: a way to describe the data with a schema. You could use an existing language such as JSON Schema , but in practice that’s clunky and everybody develops their own language.
;; Let's model users. We want to know the user's name and the year of birth.
;; Schema
(require '[schema.core :as schema])
(def User {:name schema/Str, :year-of-birth schema/Int})
;; Spec
(require '[clojure.spec.alpha :as spec])
(spec/def ::year-of-birth int?)
(spec/def ::name string?)
(spec/def ::user (spec/keys :req-un [::name ::year-of-birth]))
Validation.The basic operation is to validate data against a schema. What is interesting is what happens when the validation fails. Easy-to-read error messages are essential for the developers, but having errors as data is a useful building block, too. For example, you could build front-end form validation on top of a data specification library, and then you’d know what was the problem and in which field.
;; Our user data example is missing the year of birth. Who gives out their
;; real year of birth, anyway, to the services we (the software industry) build?
(def a-user {:name "hello@example.com", :year-of-birth nil})
(schema/validate User a-user)
;; Execution error (ExceptionInfo) at schema.core/validator$fn (core.clj:155).
;; Value does not match schema: {:year-of-birth (not (integer? nil))}
(spec/valid? ::user a-user)
;; => false
(spec/explain ::user a-user)
;; nil - failed: int? in: [:year-of-birth] at: [:year-of-birth] spec: :user/year-of-birth
Conforming.This feature is only implemented by Spec, but the idea is more general. A data specification language allows you to declare a grammar for your data structure. Conforming is parsing your data against that grammar. The result is akin to an abstract syntax tree, and Spec calls the conversion in the other direction “unforming”.
;; The regular expression specs and spec/or reveal the power of conforming.
;; Let's model hiccup-style HTML data.
(spec/def ::hiccup
(spec/cat :tag keyword?
:options (spec/? map?),
:children (spec/* (spec/or :tag ::hiccup, :text string?))))
;; Now let's parse an anchor tag into a neat map.
(spec/conform
::hiccup
[:a {:href "http://www.example.com/"} "Check out " [:i "example.com"]])
;; {:tag :a,
;; :options {:href "http://www.example.com/"},
;; :children [[:text "Check out "]
;; [:tag {:tag :i,
;; :children [[:text "example.com"]]}]]}
Coercion.Coercion, or more generally, schema-driven transformation of data means that you walk your data and schema together and apply transformations to build new data. This allows you to do things like converting date strings in JSON to java.time instants and vice versa.
Program instrumentation.Yet another use case for data validation is to define a contract for a function: what kind of inputs it takes, what kind of data it returns, and how these are related. This is what Spec’s fdef does.
(require '[clojure.spec.test.alpha :as stest]) (defn plus [x y] (+ x y)) (spec/fdef plus :args (spec/cat :x int? :y int?) :ret int?) (stest/instrument `plus) (plus 1 2) ;; => 3 (plus 1 "2") ;; Execution error - invalid arguments to user/plus at (REPL:1). ;; "2" - failed: int? at: [:y]
Schema introspection.The ability to inspect the schema enables features such as generating JSON Schema from your schemas, as shown by spec-tools .
Performance.Data specification libraries can end up playing a pretty important role in your application. For REST APIs, JSON coercion is part of every request, and if you use instrumentation, validation is literally everywhere.
In my experience, indiscriminate use of Spec’s instrumentation makes programs crawl. Michael Borkent shared a similar experience on The REPL podcast :
If you have an application and you have like 100 core specs and then you start instrumenting those, the application becomes really really slow, even in just in development. So the overhead of calling spec validations on every function call in Clojure program becomes too much for core functions. That is what I had found and I was a little bit disappointed that it didn’t work out, so, at least for dev purpose.
The performance matters and your data specification library can become a bottleneck.
As far as I know, no data specification library for Clojure has all of the features mentioned above. Hopefully this list helps you to choose one – or to decide to roll your own!
以上所述就是小编给大家介绍的《Essential features of data specification libraries》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
数学之美 (第二版)
吴军 / 人民邮电出版社 / 2014-11 / 49.00元
几年前,“数学之美”系列文章原刊载于谷歌黑板报,获得上百万次点击,得到读者高度评价。读者说,读了“数学之美”,才发现大学时学的数学知识,比如马尔可夫链、矩阵计算,甚至余弦函数原来都如此亲切,并且栩栩如生,才发现自然语言和信息处理这么有趣。 在纸本书的创作中,作者吴军博士几乎把所有文章都重写了一遍,为的是把高深的数学原理讲得更加通俗易懂,让非专业读者也能领略数学的魅力。读者通过具体的例子学到的......一起来看看 《数学之美 (第二版)》 这本书的介绍吧!
CSS 压缩/解压工具
在线压缩/解压 CSS 代码
MD5 加密
MD5 加密工具