title: How to remove extra keys from internal map using spec-tools
body: <p>I'm trying to use clojure.spec and <a href="https://github.com/metosin/spec-tools" rel="nofollow noreferrer">metosin/spec-tools</a> to validate and conform data in my application. After reading spec-tools documentation it was not clear to me how I should wrap my specifications using <code>spec-tools.core/spec</code> so that the conformed data don't have extra keys (it works on a top level map but not on maps on inner structures).</p>
  
  <p>Some code to help clarify the problem:</p>
  
  <pre><code>(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])))
  </code></pre>
  
  <p>Now suppose I have the following data that I want to validate/conform:</p>
  
  <pre><code>(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"}]
  </code></pre>
  
  <p>I tried changing the <code>:req.product.create/images</code> declaration to include <code>st/spec</code> call wrapping the <code>s/*</code> form, or the <code>s/keys</code> form, or both, but that changes didn't change the result.</p>
  
  <p>Any ideas how I can solve this problem?</p>