Как убрать лишние ключи с внутренней карты используя spec-tools
Я пытаюсь использовать clojure.spec и https://github.com/metosin/spec-tools для проверки и согласования данных в моем приложении. После прочтения документации по спец-инструментам мне не было ясно, как мне обернуть свои спецификации, используя spec-tools.core/spec
так что согласованные данные не имеют дополнительных ключей (это работает на карте верхнего уровня, но не на картах на внутренних структурах).
Некоторый код, чтобы помочь прояснить проблему:
(ns prodimg.spec
(:require [clojure.spec.alpha :as s]
[spec-tools.core :as st]
[spec-tools.spec :as st.spec]))
(def ^:private not-blank? #(and (string? %)
(not (clojure.string/blank? %))))
(s/def :db/id integer?)
(s/def :model.image/id :db/id)
(s/def :model.image/type not-blank?)
(s/def :model.image/product-id :db/id)
(s/def :model.product/id :db/id)
(s/def :model.product/parent-id (s/nilable :db/id))
(s/def :model.product/name not-blank?)
(s/def :model.product/description string?)
(s/def :model.product/price (s/nilable decimal?))
; ----- request specs -----
; create product
(s/def :req.product.create/images (s/* (s/keys :req-un [:model.image/type])))
(s/def :req.product.create/children
(s/* (s/keys :req-un [:model.product/name :model.product/description]
:opt-un [:model.product/price])))
(s/def :req.product/create
(st/spec (s/keys :req-un [:model.product/name :model.product/description]
:opt-un [:model.product/price
:model.product/parent-id
:req.product.create/images
:req.product.create/children])))
Теперь предположим, что у меня есть следующие данные, которые я хочу проверить / согласовать:
(def data {:name "Product"
:description "Product description"
:price (bigdec "399.49")
:extra-key "something"
:images [{:type "PNG" :extra-key "something else"}])
(st/conform :req.product/create data st/strip-extra-keys-conforming)
; below is the result
; {:name "Product"
:description "Product description"
:price 399.49M
:images [{:type "PNG" :extra-key "something else"}]
Я пытался изменить :req.product.create/images
декларация для включения st/spec
обернуть s/*
форма или s/keys
форма, или оба, но эти изменения не изменили результат.
Есть идеи, как я могу решить эту проблему?
1 ответ
Странно, с последней версией [metosin/spec-tools "0.5.1"]
выпущенный 2017-10-31 (так до вашего поста), единственное изменение, которое я должен был сделать, - это следовать примеру в документации в разделе соответствия карт, что, похоже, является одной из попыток, которые вы уже попробовали: wrap s/keys
с st/spec
следующее:
+ Изменить
(s/def :req.product.create/images (s/* (s/keys :req-un [:model.image/type])))
в
(s/def :req.product.create/images (s/* (st/spec (s/keys :req-un [:model.image/type]))))
и я получаю ожидаемый результат:
(st/conform :req.product/create data st/strip-extra-keys-conforming)
=>
{:description "Product description",
:images [{:type "PNG"}],
:name "Product",
:price 399.49M}