Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse routing params conforming #75

Closed
malchmih opened this issue Mar 18, 2018 · 6 comments
Closed

Reverse routing params conforming #75

malchmih opened this issue Mar 18, 2018 · 6 comments

Comments

@malchmih
Copy link

malchmih commented Mar 18, 2018

I'd be useful to have coercion to work with reitit/match-by-name. One example is conforming keyword to a string path parameter.
Related spec-tools issue: metosin/spec-tools#112

(r/match-by-name
  (r/router
    ["/olipa/:kerran" ::avaruus])
  ::avaruus
  {:kerran :joskus})
;#Match{:template "/olipa/:kerran",
;       :data {:name :user/avaruus},
;       :result nil,
;       :path-params {:kerran :joskus},   <-- wrong
;       :path "/olipa/:joskus"}           <-- wrong
@ikitommi
Copy link
Member

ikitommi commented Mar 18, 2018

This should be polymorphic. Alternatives:

1) Use JSON encoder

  • most likely does the job already.
  • requires dependency to JSON library
  • compojure-api does this

2) Multimethod

  • e.g. reitit.core/stringify
  • Easy to implement
  • Value-based, works for all coercion instances
  • Slow(er than Protocol)
  • Adding new types (e.g. LocalTime) requires imperative registration.
    • Extending just for routing, can't (shoudn't) use it elsewhere

3) Protocol

  • e.g. reitit.core/Stringify
  • Easy to implement
  • Value-based, works for all coercion instances
  • Fast(er than Multimethod)
  • Adding new types (e.g. LocalTime) is more declarative
    • Extending just for routing, can't (shoudn't) use it elsewhere
  • bidi does this

4) Coercion/Type-based

  • bijections, defined for all types of coercion
  • both coercion & uncoercion defined in the type meta data
  • works for all use cases, not just routing (where else this is really needed?)
  • parameter type needs to be defined in order to work
  • e.g. with spec tools to keyword?:
(st/spec
  {:spec keyword?
   :description "a bijecting keyword"
   ::encode/string #(name %2)
   ::decode/string #(keyword %2)})

NOTE: qualified keywords as path-parameters need to be url-encoded, as otherwise the / with mess up the generated path. We still could use the generic ::encode/string, just url-encode the results.

@malchmih
Copy link
Author

From my point of view, 3rd option (Protocol) is the more natural choice here, since I don't see any other usage of this except for the routing

@ikitommi
Copy link
Member

I think it's the way to go. When/if 4rd is implemented, it can be used instead. Would you like to do a PR?

@ikitommi
Copy link
Member

I have extra time just now, will do this.

@ikitommi
Copy link
Member

#76

@ikitommi
Copy link
Member

fixed in [metosin/reitit-core "0.1.1-20180322.170157-5"].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants