This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-02-23
Channels
- # announcements (2)
- # atom-editor (3)
- # babashka (49)
- # beginners (100)
- # biff (9)
- # calva (78)
- # clj-kondo (18)
- # clojure (143)
- # clojure-europe (13)
- # clojure-germany (1)
- # clojure-nl (2)
- # clojure-spec (5)
- # clojure-sweden (2)
- # clojure-uk (4)
- # clojurescript (58)
- # conjure (1)
- # cursive (4)
- # datascript (11)
- # datomic (63)
- # docker (7)
- # emacs (18)
- # events (1)
- # fulcro (18)
- # graalvm (5)
- # helix (4)
- # improve-getting-started (13)
- # jobs (4)
- # jobs-discuss (3)
- # lsp (15)
- # malli (90)
- # membrane (14)
- # off-topic (12)
- # other-languages (5)
- # pedestal (7)
- # polylith (53)
- # re-frame (15)
- # reitit (23)
- # releases (4)
- # remote-jobs (9)
- # ring (11)
- # shadow-cljs (90)
- # specter (2)
- # testing (3)
- # tools-build (63)
- # vim (2)
- # xtdb (8)
just some thoughts in case its related, I am using transit+json because my keys are namespaces this is so they get preserved over the wire
I tried to apply this https://github.com/metosin/malli/pull/545/files
:parameters
{:body
[:map
[:scrape-request
[:map
[:id int?]
[:from-date
[:map
{:registry
#:my-name-space{:zdt :zoned-date-time}}
:my-name-space/zdt]]]]]},
Execution error (ExceptionInfo) at reitit.exception/exception (exception.cljc:19).
:malli.core/invalid-schema {:schema :zoned-date-time}
{:schema :zoned-date-time}
:parameters
{:body
[:map
[:scrape-request
[:map [:id int?] [:from-date :zoned-date-time]]]]},
If you're using the default registry, you need to make sure it registers :zoned-date-time
as a known schema. See:
https://github.com/metosin/malli/blob/2398df55ee806e25592fabf4d0c642ee3a2b233f/src/malli/core.cljc#L2371-L2378
@U05476190 thanks, I did small step forward. The route construction no longer fails after I defined the custom registry via :coercion
(defn service-routes []
["/api"
{:coercion (reitit.coercion.malli/create
(merge reitit.coercion.malli/default-options
{:options {:registry (merge
(m/default-schemas)
(malli-time/time-schemas))}}))
Sorry, no idea; probably best to ask outside of this thread - I'm not familiar with swagger/malli integration
will try to update https://github.com/metosin/malli/pull/545/files with
Thanx @lambder, I was trying to add support for java.time.LocalDate
and java.time.Instant
to my project, and your post helped me.
I added the code from https://github.com/metosin/malli/pull/545/files and imported it to the registry with
(defn service-routes []
["/api"
{:coercion (reitit.coercion.malli/create
{:options {:registry (merge
(m/default-schemas)
(malli-time/time-schemas))}})
(I believe the merge with default-options is not necessary, as reitit.coercion.malli/create
already does that)
I was then able to coerce a string to java.time.LocalDate
by specifying the property as:
[:mydate {:description "My description"
:json-schema/example "2021-11-05"}
:local-date]
One thing I noticed, was that if I tried to send a non-parsable value, I got
Error: Wrong number of args (2) passed to: slakt-service.malli.time/->error-reporter/-report--28426
By changing
(defn ->error-reporter
[parser message]
(fn -report [value]
to
(defn ->error-reporter
[parser message]
(fn -report [value _]
I instead got the message
"Should be local-date or LocalDate"
Yes. I was also wondering about type vs format. Not an expert on json schema, but looks like you are right
I also added :json-schema/example:
:local-date {:class LocalDate :parser -string->local-date :json-schema/type :local-date :json-schema/example "2022-02-23"}
...
:json-schema/example (:json-schema/example props -name)
Then I don’t have to (but could override if I want to) provide example in my schema.If I don’t provide json-schema/example, Swagger will show “Unknown Type: local-date”. Maybe your change to
"type": "string",
"format": "date-time"
is what makes Swagger able to provide an examplecustomDate:
type: string
pattern: '^\d{4}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$'
description: Custom date
example: "20210130"
Isn’t “date” a good fit for java.time.LocalDate? Format yyyy-MM-dd
With
:local-date {:class LocalDate :parser -string->local-date :json-schema/type :string :json-schema/format "date"}
Swagger provides an example :thumbsup:{:transformers {:body {:default default-transformer-provider
:formats {"application/json" json-transformer-provider}}
:string {:default string-transformer-provider}
:response {:default default-transformer-provider
:formats {"application/json" json-transformer-provider}}}
No, sorry, haven't done anything to provide support for edn in our application
{
:scrape-request {
:id 1
:from-date #time/zoned-date-time "2022-01-01T16:14:34.447Z"
}
}
{:schema "[:map {:closed true} [:scrape-request [:map {:closed true} [:id int?] [:from-date :zoned-date-time]]]]", :errors ({:path [:scrape-request :from-date], :in [:scrape-request :from-date], :schema ":zoned-date-time", :value (. java.time.ZonedDateTime parse "2022-01-01T16:14:34.447Z"), :message "Should be zoned-date-time or ZonedDateTime"}), :value {:scrape-request {:id 1, :from-date (. java.time.ZonedDateTime parse "2022-01-01T16:14:34.447Z")}}, :type :reitit.coercion/request-coercion, :coercion :malli, :in [:request :body-params], :humanized {:scrape-request {:from-date ["Should be zoned-date-time or ZonedDateTime"]}}}
(m/-simple-schema
{:type type
:type-properties
(cond-> {:error/fn error-fn
:decode/json {:enter safe-parser}
:encode/json {:enter #(prn %)}
:json-schema/type (:json-schema/type props -name)}
(:json-schema/format props -name) (assoc :json-schema/format (:json-schema/format props -name)))
:pred pred})
so this :from-date (. java.time.ZonedDateTime parse "2022-01-01T16:14:34.447Z")
looks a lot like (ZonedDateTime/parse x)
funny thing the value to decoder is coercion.malli is already wrapped with something like this:
@lambder those decode/json transformations aren't used by coercion here (no coercion really needed for these values) when you are using EDN. As EDN can already represent types, the coercion doesn't do anything.
If you have *data-reader*
registered for the #time/zoned-date-time
tag (or provided :readers
option to muuntaja edn format) the value should be correct and the problem must be with the schema validation (the predicate).
hey @juhoteperi no, I don't have the readers supplied to muuntaja sepcially
(def instance
(m/create
(-> m/default-options
(update-in
[:formats "application/transit+json" :decoder-opts]
(partial merge time/time-deserialization-handlers))
(update-in
[:formats "application/transit+json" :encoder-opts]
(partial merge time/time-serialization-handlers)))))
Muuntaja will use *data-readers*
, which is already provided by Clojure if you have the readers in a data_readers.clj
file somewhere
But hmm, it could be problem with those data readers, because :value (. java.time.ZonedDateTime parse "2022-01-01T16:14:34.447Z")
seems really strange. Looks like the value isn't the ZonedDateTime instance, but the Clojure form calling that ZonedDateTime/parse method
> The library includes the magic file data_readers.cljc which Clojure and the Clojurescript compilers() will look for.
So just including time-literals in the classpath should add data-readers for those tags
If data-readers are working correctly, if you eval in the REPL {:foo #time/zoned-date-time "2022-01-01T16:14:34.447Z"}
you should get the same map back, the tagged value is read to ZonedDateTime instance, and because you have the print method registered, it should be printed out the same way.
@juhoteperi this is just black magic to me