-
Notifications
You must be signed in to change notification settings - Fork 259
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
Use coercion to encode query-string values in match->path #716
Conversation
ba4e307
to
ea61818
Compare
607d7c7
to
f60a7ad
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Note: currently collections in query-parameters are encoded as field-value | ||
pairs separated by &, i.e. \"?a=1&a=2\", if you want to encode them | ||
differently, convert the collections to strings first." | ||
By default currently collections in query parameters are encoded as field-value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "By default, collections ..." would read a bit better
(let [;; Always allow extra paramaters on query-parameters encoding | ||
open-schema (mu/open-schema schema) | ||
;; Do not remove extra keys | ||
string-transformer (-transformer string-transformer-provider (assoc options :strip-extra-keys false)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello! We've been testing these changes and we have a problem when using custom transformers. We think the problem might be this line. This line is ignoring the transfomers
(there is a typo too) parameter and hard-coding string-transfomer-provider
instead of using the transformers
defined in the Reitit router configuration. Maybe it should be something like this?:
(defn- -query-string-coercer
"Create coercer for query-parameters, always allows extra params and does
encoding using string-transformer."
[schema transfomers options]
(let [;; Always allow extra paramaters on query-parameters encoding
open-schema (mu/open-schema schema)
;; Do not remove extra keys
;; BEFORE: (-transformer (get-in transfomers [:string :default]) (assoc options :strip-extra-keys false))
string-transformer (get-in transfomers [:string :default])
encoder (m/encoder open-schema (assoc options :strip-extra-keys true) string-transformer)]
(fn [value format]
(if encoder
(encoder value)
value))))
Is there any reason for hard-coding string-transformer-provider
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason is that create
fn processes transformers
map and applies the options to TransformerProviders, then the transformer we see after that step is one with mt/strip-extra-keys-transformer
combined with the string-transformer.
- We can probably use the transformers value before options are applied for this code
- the options are just applied to the default TransformationProvider values, when you provide a concrete transformer instance yourself, this doesn't apply
- while
m/encoder
takes options map,:strip-extra-keys
isn't one of the options that would be used there (AFAIK). This option is only used for reitit.malli.coercion TransformationProviders: https://github.com/metosin/reitit/blob/master/modules/reitit-malli/src/reitit/coercion/malli.cljc#L27-L33
I'll see what I can do.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, you're right. The encoder doesn't take the :strip-extra-keys
option.
Maybe one solution could be to have a specific query string transformer provider that doesn't include the :strip-extra-keys
transformer and include it by default in the Reitit router configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lucassousaf Check the latest commit, :string transformer will be used now. I did consider adding a new transfomers option for query-string encoding, but I think decoding and encoding should use the same transformer so using :string does seem good idea now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good! At first glance it seems to work as expected. If we find anything (I don't think so, looks good) we can open an issue. Thanks a lot for your work @Deraen !
This is the initial version of extending Reitit code and the frontend module to encode query-string parameter values using the Malli schema and string transformer.
Coercion already allowed parsing query-string strings using Malli and even per schema property using the
:decode/string
option. Implementing this also for URL generation (href, push/replace-state, etc.) makes sense because Malli also supports value encoding using the schemas.Changes:
Coercion implementation for Malli. Spec and Schema are a no-op at this point. We need to consider whether they can also support this case.
TODO
Consider if query-coercer can be "precompiled" in reitit.frontend/router, so the coercer and transformers don't need to be recreated each timeSeparate or further work