Fork me on GitHub
#reitit
<
2018-03-18
>
malch11:03:57

Is there a way to enable the coercion for the match-by-name?

ikitommi13:03:33

@malch which way? could you give an example?

malch13:03:10

@ikitommi sure, something like this

(def router
    (reitit/router
     ["/add-user/:tab" {:name ::home-add-user
                        :coercion reitit.coercion.spec/coercion
                        :parameters {:path {:tab keyword?}}}]
     {:compile reitit.coercion/compile-request-coercers}))

  (defn match-by-path-and-coerce! [path]
    (when-let [match (reitit/match-by-path router path)]
      (assoc match :parameters (reitit.coercion/coerce! match))))

  (match-by-path-and-coerce! "/add-user/admin")
  ;; {:template "/add-user/:tab",
  ;;  :data
  ;;  {:name :transportal.routes/home-add-user,
  ;;   :coercion #object[reitit.coercion.spec.t_reitit$coercion$spec127758],
  ;;   :parameters {:path {:tab #object[cljs$core$keyword_QMARK_]}}},
  ;;  :result {:path #object[Function]},
  ;;  :path-params {:tab "admin"},
  ;;  :path "/add-user/admin", 
  ;;  :parameters {:path {:tab :admin}}}

  (reitit/match-by-name router ::home-add-user {:tab :admin})
  ;; {:template "/add-user/:tab",
  ;;  :data
  ;;  {:name :transportal.routes/home-add-user,
  ;;   :coercion #object[reitit.coercion.spec.t_reitit$coercion$spec127758],
  ;;   :parameters {:path {:tab #object[cljs$core$keyword_QMARK_]}}},
  ;;  :result {:path #object[Function]},
  ;;  :path-params {:tab :admin}, 
  ;;  :path "/add-user/:admin"}

malch13:03:23

in the last result i'd like to have "/add-user/admin", not "/add-user/:admin"

malch13:03:18

I'm replacing bidi with reitit in our project and this is the first thing that doesn't work "out of the box"

ikitommi13:03:53

@malch you could add match-by-name-and-coerce!, both matches return Match

malch13:03:09

@ikitommi tried that:

(defn match-by-name-and-coerce! [name params]
    (when-let [match (reitit/match-by-name router name params)]
      (assoc match :parameters (reitit.coercion/coerce! match))))

  (match-by-name-and-coerce! ::home-add-user {:tab :admin})
  ;; {:template "/add-user/:tab",
  ;;  :data
  ;;  {:name :transportal.routes/home-add-user,
  ;;   :coercion #object[reitit.coercion.spec.t_reitit$coercion$spec127758],
  ;;   :parameters {:path {:tab #object[cljs$core$keyword_QMARK_]}}},
  ;;  :result {:path #object[Function]},
  ;;  :path-params {:tab :admin},
  ;;  :path "/add-user/:admin", 
  ;;  :parameters {:path {:tab :admin}}}

malch13:03:46

I'm not sure if I'm doing this right way though

malch13:03:06

But I'm guessing it won't work this way

malch13:03:36

Since we need "reverse coercion" here

malch13:03:12

When matching by path coercion is str->keyword

malch13:03:25

By name - keyword->str

ikitommi14:03:42

oh, I see. One option would be run JSON encoding on the params. Would transform dates etc.

ikitommi14:03:02

But, I think this should be resolved at type/spec level.

ikitommi14:03:45

… and as we also maintain spec-tools, it should be trivial to add this there.

ikitommi14:03:22

Multimethods (`stringify`) or Protocol (`Stringify`) would also work, but that would make adding new types hard - too many things to extend.

ikitommi14:03:57

Just added few days ago the support for self-contained (conforming) Specs into spec-tools, maybe just do the same for the other way, would be something like “spec bijections”. Maybe like this?

(require '[spec-tools.core :as st])
(require '[spec-tools.conform :as conform])
(require '[spec-tools.unform :as unform]) ;; new

(def my-keyword?
  (st/spec
    {:spec keyword?
     :description "a bijecting keyword"
     ::unform/string #(name %2)
     ::conform/string #(keyword %2)}))

;;
;; string -> keyword
;;

(st/conform my-keyword? "kikka") ; => ::s/invalid

(st/conform my-keyword? "kikka" st/string-conforming) ; => :kikka

;;
;; keyword -> string
;;

(st/unconform my-keyword? :kikka) ; => :kikka

(st/unconform my-keyword? :kikka st/string-conforming) ; => "kikka"

ikitommi14:03:33

@malch could you write an issue to reitit of this? need to give it a though.

ikitommi14:03:49

wrote an issue of the bijection to spec-tools anyways already: https://github.com/metosin/spec-tools/issues/112

malch14:03:26

@ikitommi Sure, will do, thanks for you help!

ikitommi18:03:13

added alternatives to the issue. comments welcome.