lambdaisland / uri

A pure Clojure/ClojureScript URI library
Mozilla Public License 2.0
243 stars 21 forks source link

Query-string parsing does not retain strict ordering #35

Closed ilmoraunio closed 1 year ago

ilmoraunio commented 1 year ago

Parsing query-string does not retain the strict order of the query-string parameters. This becomes a problem when you reconstruct the query-string from a parsed query-params map.

Example:

(-> (uri/query-string->map "a=1&b=2&c=3&d=4&e=5&f=6&g=7&h=8&i=9")
    (merge {:foo "bar"})
    (uri/map->query-string))
=> "e=5&g=7&c=3&h=8&foo=bar&b=2&d=4&f=6&i=9&a=1"

One option could be to expose an ordered? field. Based on the field we would then use a hash-map (like we do now) or an insertion-order-based map (such as clj-commons/ordered). Like so:

(-> (uri/query-string->map "a=1&b=2&c=3&d=4&e=5&f=6&g=7&h=8&i=9" {:ordered? true})
    (merge {:foo "bar"})
    (uri/map->query-string))
=> "a=1&b=2&c=3&d=4&e=5&f=6&g=7&h=8&i=9&foo=bar"

Another option could be to expose a parameter to provide the map implementation for uri/query-string->map, say, using a :ordering-strategy. This would especially be a more viable option if keeping this library light for the cljs side is a primary consideration.

If this makes sense and we can agree on the approach, I might be able to have some time to work on this.

ilmoraunio commented 1 year ago

I properly read through the contribution guide and decided to take a stab at it in above PR.