domkm / silk

Routing for Clojure & ClojureScript
222 stars 13 forks source link

Fixes #7 #10

Closed Deraen closed 9 years ago

Deraen commented 9 years ago

Hi,

I took a stab at fixing #7. I'm not perfectly happy how depart works with default parameters as it writes the default parameter to the url.

Decode-query now returns empty map for empty string. This way query string pattern defaults should work even if url has no query params at all. This shouldn't be problem as encode-url returns an empty query-string for empty map.

Deraen commented 9 years ago

I think using e.g. {:q nil} as a default should also be supported, but this doesn't allow that.

domkm commented 9 years ago

Thanks, Juho! I really appreciate you providing a patch for this and for explaining the tradeoffs.

Since @geraldodev, @leblowl, and @sritchie have run into this issue as well, I'd like to hear their thoughts on this patch. Would it be problematic if depart returned a URL with default params or if nil was an invalid default param value?

Deraen commented 9 years ago

Hi,

I've been thinking about this a bit more since Friday and I think supporting nil as valid default param would be quite important. I would perhaps even make the second param of ? optional.

(def routes (silk/routes {:search [["search"] {"q" (silk/? :q)}]}

(silk/arrive "/search") => {:name :search}
(silk/arrive "/search?q=foo") => {:name :search :q "foo"}

(silk/depart :search) => "/search"
(silk/depart :search {:q "foo"}) => "/search?q=foo"

The current solution to this search route requires me to have two routes: :search and :search-q as I couldn't get depart working with two routes with the same name. And wrapping the query params map in ? would require me to provide non-nil default.

sritchie commented 9 years ago

I love the idea of supporting nil as a valid default and allowing an optional second param. +1.

Deraen commented 9 years ago

I'll try to update my branch tomorrow with tests for allowing nil etc. and I'll see if I can get the implementation working.

Deraen commented 9 years ago

Okay,

I added some tests and a possible implementation. But I think this should probably be improved still: Now the ? implementation is too specific to maps and it probably shouldn't be?

sritchie commented 9 years ago

this API looks good to me. I'd love to try this out, if @DomKM is willing to publish a snapshot. Thanks again!

domkm commented 9 years ago

Absolutely! Quick question for @Deraen first, what do you mean that this implementation of ? is too specific to maps? Will this patch break any uses of ? that work with the current implementation?

Deraen commented 9 years ago

I'm not exactly sure of the all the uses of ?, the tests seem to currently use it only with maps. I don't think this breaks any uses but if default-params is not provided to the ? the implementation will create a map:

The defaults make sense when ptrn is keyword, but for e.g. regexPattern not so much:

user=> (silk/match {"a" (silk/? (silk/int :a))} {})
{#domkm.silk.RegexPattern{:param-key :a, :regex #"\d+", :deserialize #<silk$int$fn__14777 domkm.silk$int$fn__14777@7e0ace58>, :serialize #<core$str clojure.core$str@1988a9c1>, :validate #<core$integer_QMARK_ clojure.core$integer_QMARK_@6238c6f9>} nil}
Deraen commented 9 years ago

I can think of several ways to improve this:

Probably the first option would be the simplest (extending the current implementation to work with other Patterns). Does this make any sense?

domkm commented 9 years ago

Thanks for your work on this, @Deraen!

I just cut 0.1.0-SNAPSHOT. Feedback greatly appreciated. CC @sritchie @leblowl @geraldodev

sritchie commented 9 years ago

This fixes my bug. Thanks for the work on this, guys.