Re: [whatwg/url] Introduce a variant of url.searchParams that operates according to URL rules instead of <form> rules (#491)

I'm experimenting with a new query params interface for my URL library, and I figured some of the ideas might be useful for future web APIs.

The model I'm going with is that, rather than "query parameters", this is modelled as a key-value string within an opaque URL component. A handful of components don't have any defined internal structure - that includes the query, but also the fragment, and we also have opaque hosts and paths. Technically, you could encode a key-value string in any of them.

[Media fragments](https://www.w3.org/TR/media-frags/) are an example of key-value pairs within the fragment:
```
http://www.example.com/example.ogv#track=audio&t=10,20

```

As is [OAuth 2.0](https://www.rfc-editor.org/rfc/rfc6749#section-4.2.2):
```
If the resource owner grants the access request, the authorization
server issues an access token and delivers it to the client by adding
the following parameters to the fragment component of the redirection
URI using the "application/x-www-form-urlencoded" format

http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA&state=xyz&token_type=example&expires_in=3600

```

I also found an App called [FoxyProxy](https://getfoxyproxy.org/developers/proxyprotocol/) (😅) which allows issuing commands via key-value pairs in a URL with opaque path. For example:
```
proxy:host=foo.com&port=999&action=add
```

So I think there is a general problem: these opaque URL components exist so that developers can encode custom structured data in their own identifiers. Key-value strings are just one example; comma-separated lists are another kind of structure that could be better supported. There really aren't great APIs for reading and manipulating these kinds of things in general - there's one kind of key-value string in one component which does have great, convenient APIs, and everything else is sort of forgotten about. People tend to hack stuff together to make up for it, and it's quite awkward and easy to make mistakes.

In Swift (the language my library is for), I'm able to define a schema object which allows customising which characters are interpreted as delimiters, which are written as delimiters, as well as options for escaping. Users can then do something like this:

```swift
var url = WebURL("http://example.com")!

// 'commaSeparated' is a user-defined schema object.
// Even though it is a custom KVP schema operating in the fragment,
// the API generalises so it is still super-easy to read/write key-value pairs.

url.withMutableKeyValuePairs(in: .fragment, schema: .commaSeparated) { kvps in
  kvps += [
    "foo": "bar",
    "baz": "qux"
  ]
}
print(url) // "http://example.com#foo:bar,baz:qux"
           //                    ^^^^^^^^^^^^^^^^

// You can also just get a view object, which doesn't need any awkward nesting.
// Again, generalises so it is really easy to use even for non-query params.

let kvps = url.keyValuePairs(in: .fragment, schema: .commaSeparated)
kvps["foo"]  // "bar"
```

The goal of an API like this which can scale to different use-cases is that it allows people to do more advanced things with URLs, more easily. It could also be an idea for the web, and the various places web technologies are used.

I also quite like that it dilutes the idea of "query parameters" as being some kind of special, proper URL component - they end up being just one expression of a general ability to encode opaque data.

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/url/issues/491#issuecomment-1301256005

You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/url/issues/491/1301256005@github.com>

Received on Wednesday, 2 November 2022 21:05:48 UTC