change the name of `merge` or at least mention differences?
I was trying to merge some new query params to existing ones with merge, but to my surprise that merge creates a new URI with path, query etc. instead of merging them with the old ones. This is quite confusing to me before I read the implementation since the merge on Dict actually "merge" the old one with the new one together. I'm wondering if the name of merge should be changed to something else so it is clearer?
On the other hand, I'm wondering if there could be such a method that adds some new properties to the existing query. E.g it's useful when a REST API is provided via a path https:://auth.ibmq.com/api which is parsed as "https:://auth.ibmq.com" and "/api" as its path, then a method that join the path of the REST API calls would be very convenient to produce things like "https:://auth.ibmq.com/api/loginWithAuth"
PS. I think probably let the URI constructor take some keywords makes more sense than overloading merge in this case.
I'm wondering if the name of merge should be changed to something else so it is clearer?
Note that generic URIs syntax has no concept of key value pairs for the query portion - it simply has a string for the query. This is why URIs.queryparams is a utility function for the common convention of &-separated key value pairs rather than these being parsed as part of URI construction. Key-value pairs are mentioned in https://tools.ietf.org/html/rfc3986#section-3.4 but it's only an example, not meant to be normative.
So I'm not quite sure we should change merge to manipulate the query string. Though I can see that it makes a certain amount of sense.
then a method that join the path of the REST API calls would be very convenient
I think joinpath(::URI, relpath::AbstractString) would have the correct semantics? How about this sketch
julia> u = URI("http://example.com/foo")
URI("http://example.com/foo")
julia> Base.joinpath(u::URI, path_components::AbstractString...) = merge(u, path=join((u.path, path_components...), '/'))
julia> joinpath(u, "bar")
URI("http://example.com/foo/bar")
julia> joinpath(u, "bar", "baz")
URI("http://example.com/foo/bar/baz")
PS. I think probably let the URI constructor take some keywords makes more sense than overloading merge in this case.
Yes, I think this should be done and we should deprecate the current merge which has a specific meaning not really consistent with Base.merge.
Note that generic URIs syntax has no concept of key value pairs for the query portion
I think overloading merge is fine, since by Julia's definition in Base merge is defined on several dict-like objects, it doesn't have to be in the URI standard but more like a convenient one-liner defined in Julia - we can't show people what the standard is via interfaces I guess? to my understanding the URI specification is more about parsing not other things.
Base.merge(uri::URI, d::Dict) = URI(uri; query=merge(queryparams(uri), d))
I'll make a PR of the rest changes then.
it doesn't have to be in the URI standard but more like a convenient one-liner defined in Julia
Very true. My thought was that we'd have to combine the existing query string with the new key value pairs, and that would be making a possibly invalid assumption about the format of that string. But perhaps that's not something to worry about.
umm, so what about just support this convenient one-liner first and see what happens?
so what about just support this convenient one-liner first and see what happens?
Yeah I think that'd be ok. For merge we'd have to wait a deprecation cycle. To be honest, I think we could just name it mergequery() and be done with it.
merge is being deprecated for URI(::URI; kw...), right? https://github.com/JuliaWeb/URIs.jl/blob/97a4f3087fa92bfb779b88682b3e1b03a6c82691/src/deprecate.jl#L1-L4
yes, I think that's what I originally posted this issue for then I submitted a PR.