I've been playing and like Silk a lot! However the following I find curious as I'm wondering what the intended behaviour should be: user=> (silk/match (silk/composite ["user-" (silk/integer :id) "-fred" (silk /option :this "that") "s"]) "user-42-fredjs") {:id 42, :this "j"}
user=> (silk/match (silk/composite ["user-" (silk/integer :id) "-fred" (silk /option :this "that") "s"]) "user-42-freds") nil I would have thought the last one would have produced: user=> (silk/match (silk/composite ["user-" (silk/integer :id) "-fred" (silk /option :this "that") "s"]) "user-42-freds") {:id 42, :this "that"} My only other suggestion, not worthy of a pull request, is the following: (defn domkm.silk/encode-query "Takes a query map. Returns a string of query pairs encoded and joined." [query] (->> query (apply into sorted-map) ; ensure consistent ordering to improve cache-ability of URLs... (map (fn [[k v]] (str (encode k) "=" (encode v)))) (str/join "&"))) Regards, Marc On Sunday, 10 August 2014 05:00:50 UTC+10, DomKM wrote: > > Hi Allen, > > Thanks for the feedback! > > 1) This, and precompiling regexes where possible, is my intention with > Silk. > > 2) I'm not convinced that requiring fully-qualified routes would be a > feature. Let's say we have route A which should match "/foo/bar" and > route B which should match "/foo/*". If these routes are unordered, route B > would have to additionally be constrained with `(not= * "bar")`. It seems > like this could make route definition very painful when working in a > large application with many routes that match on multiple parts of the URL. > > > On Sat, Aug 9, 2014 at 10:06 AM, Allen Rohner <aro...@gmail.com > <javascript:>> wrote: > >> I'd like to thank everyone in the community for both Silk, and Secretary. >> >> I'll throw out some (uninvited) feature requests I'd love to see in a >> future route-matching library. >> >> 1) Make trie-based route dispatching possible. A feature pedestal >> has/will soon have, is to compile the routing table into trie, rather than >> the compojure-style wrapped functions. This can have a nice speedup on busy >> applications. I'm not asking anyone to write this code, just consider the >> design such that it's possible to add this behavior in the future. >> >> 2) I'll claim that making route definition order is a misfeature. Routes >> should always be fully qualified, such that re-arranging them doesn't >> affect routing behavior (and therefore, the route table should be an >> unordered collection, like a map or set, not a vector). One nice >> readability reason for this is that if your route order does matter, than >> at least one route definition is "lying" about which routes it actually >> dispatches on. >> >> Just things to consider :-) >> >> Thanks, >> Allen >> >> >> On Thursday, August 7, 2014 9:31:56 PM UTC-5, DomKM wrote: >> >>> Thanks for your feedback, Dylan! >>> >>> If you define routes with :path and :query, will the route match/unmatch >>>> with undefined query keys? If so, how are they handled? If not, I'd >>>> suggest >>>> making query matching optional, where nils are substituted. >>> >>> >>> I'm not entirely sure what you mean, but I'll give it a shot. Please >>> provide some example code if I answered the wrong question. >>> >>> `nil` is a pattern that matches anything. If your URL pattern query is >>> `nil` then the URL query will not be checked. >>> A map is a pattern that matches its values against the values of another >>> map. Therefore, `nil` and `{}` are equivalent when used as a query pattern. >>> You can make a query value pattern optional by wrapped it with >>> `silk/option`. >>> >>> It's a little unclear how your matching functions relate to route. It >>>> looks like Silk always breaks at / in path and matches, is that correct? >>> >>> >>> Yes. There is a URL type in Silk and matching is done against instances >>> of it. The path is represented as a vector of segments. >>> >>> The readme is currently very deficient and I apologize for that. >>> >>> There are some really good things in secretary. What do you think about >>>> them? >>>> Splat, regex, format matchers. >>> >>> >>> In terms of regex matching, Silk used to have a built-in regex pattern >>> but I removed it when I made a big architectural change. I forget why I >>> removed it, but I'll re-add it since it does seem like a very common >>> requirement. >>> >>> Currently, part of Secretary's splat exists as a built-in Silk pattern. >>> For example, `(silk/composite ["foo" :* "bar"])` would match >>> "fooanythingbar" and return `{:* "anything"}`. The `:*` isn't special; it's >>> just a keyword. Format is just a specific case of composite: >>> `(silk/composite [:* "." :format])`. Unlike Secretary, Silk does not have a >>> built-in special syntax for string patterns. This is because special syntax >>> strings are not composable and, since Silk matches against unencoded >>> strings, who am I to say you can't have ":" or "*" in your URL paths? ;) >>> >>> Looking at the Secretary readme, there appear to be two ways to use >>> splat that Silk currently does not have built-in support for. In Secretary, >>> "/foo/*" would match "/foo/bar/baz" and return `{:* "bar/baz"}`. Also, >>> "/*/*" would match "/a/b" and return `{:* ["a" "b"]}`. I keep saying >>> "built-in" because, while multi-segment path patterns and binding the same >>> parameter key to multiple path segments does not currently exist in Silk, >>> it is very easy to extend Silk with that functionality. You could easily >>> create a pattern that did exactly what Secretary and Clout do by default >>> and use it to match a path instead of a vector. However, I do question the >>> utility of these two features. Are either of these common requirements and, >>> if so, could I see some examples of why they are necessary or helpful? This >>> isn't rhetorical; please let me know if Silk is missing something that is >>> within its scope and is useful to most consumers. >>> >>> protocol based render function for multiple arity "unmatching." this is >>>> really great. >>> >>> >>> I don't think I fully understand the use cases for this protocol. Do you >>> want to be able to look routes up by types? If so, since route names in >>> Silk can be anything, you could use a type as a name. Anyway, I put >>> together this little gist >>> <https://gist.github.com/DomKM/26658b53a50e48f0be70> of ways in which >>> Silk could be used similarly to how I *think* someone might use Secretary's >>> IRenderRoute. Do these cover the use cases for that protocol? >>> >>> >>> I also agree with everything in Joel's response and look forward to >>> working with him on improving the routing story. :) >>> >>> >>> On Thu, Aug 7, 2014 at 2:52 PM, Joel Holdbrooks <cjhold...@gmail.com> >>> wrote: >>> >>>> I'm in agreement that Silk is a step in the right direction. I've >>>> reached out to Dom and I think we can learn a lot from each other and work >>>> together to improve the routing story in Clojure overall. >>>> >>>> > There are some really good things in secretary. What do you think >>>> about them? >>>> > Splat, regex, format matchers. >>>> > protocol based render function for multiple arity "unmatching." this >>>> is really great. >>>> >>>> These are definitely nice things and I'm willing to bet Silk would be >>>> capable of supporting some of them. >>>> >>>> It's obvious to me to that if we can iron out the details with Silk, >>>> Secretary could built on top of it as a higher level interface while at >>>> the >>>> same time taking advantage of what Silk has to offer. It might mean some >>>> breaking changes in Secretary but those were already slated anyway. >>>> >>>> -- >>>> Note that posts from new members are moderated - please be patient with >>>> your first post. >>>> --- >>>> You received this message because you are subscribed to the Google >>>> Groups "ClojureScript" group. >>>> To unsubscribe from this group and stop receiving emails from it, send >>>> an email to clojurescrip...@googlegroups.com. >>>> To post to this group, send email to clojur...@googlegroups.com. >>>> >>>> Visit this group at http://groups.google.com/group/clojurescript. >>>> >>> >>> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clo...@googlegroups.com >> <javascript:> >> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to the Google Groups >> "Clojure" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to clojure+u...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.