Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relationship with URI Templates (RFC 6570) #58

Closed
dunglas opened this issue Jul 23, 2021 · 9 comments
Closed

Relationship with URI Templates (RFC 6570) #58

dunglas opened this issue Jul 23, 2021 · 9 comments

Comments

@dunglas
Copy link

dunglas commented Jul 23, 2021

Hi,

First of all, thank you for working on this topic.

There is an existing web standard (implemented by several libraries and server-side frameworks) to express URI templates: https://datatracker.ietf.org/doc/html/rfc6570

As stated in the RFC, it isn’t sufficient to create a fully-featured router, however it is sufficient for simple use cases:

Some URI Templates can be used in reverse for the purpose of variable matching: comparing the template to a fully formed URI in order to extract the variable parts from that URI and assign them to the named variables. Variable matching only works well if the template expressions are delimited by the beginning or end of the URI or by characters that cannot be part of the expansion, such as reserved characters surrounding a simple string expression. In general, regular expression languages are better suited for variable matching.

For instance, we use this syntax in the Mercure protocol to specify topics to match: https://mercure.rocks/spec#topic-selectors

This syntax is also widely used in the PHP community to define routing patterns (it is usually converted as a regex for performance by the router libraries).

For consistency with the existing standards of the web platform, shouldn’t your proposal extend the syntax defined in RFC 6570, or at least reuse the parts that can be reused (the named groups for instance)?

Also, having a pure string representation of the pattern (#22) would help interoperability. For instance, this would allow to use this syntax in the Mercure protocol (as a query parameter value) or in declarative routers.

Best regards,

@dunglas dunglas changed the title Relationship Relationship with URI Templates (RFC 6570) Jul 23, 2021
@wanderview
Copy link
Member

I spoke to @jcgregorio, one of the RFC 6570 authors, while researching the pattern syntax for URLPattern. He indicates that URI templates are not a good fit for the matching use case. He quoted this from the RFC:

Some URI Templates can be used in reverse for the purpose of variable
matching: comparing the template to a fully formed URI in order to
extract the variable parts from that URI and assign them to the named
variables. Variable matching only works well if the template
expressions are delimited by the beginning or end of the URI or by
characters that cannot be part of the expansion, such as reserved
characters surrounding a simple string expression. In general,
regular expression languages are better suited for variable matching.

In addition, there were other benefits to adopting the path-to-regexp approach. It seemed more aligned with popular routing systems with wide adoption; e.g. :foo name syntax is used in ruby on rails, etc. Also, a * style wildcard is consistent with previous web platform matching algorithms scattered through various APIs like CSP.

Also, having a pure string representation of the pattern (#22) would help interoperability. For instance, this would allow to use this syntax in the Mercure protocol (as a query parameter value) or in declarative routers.

The current implementation does support constructing a URLPattern from a single string. If you look at:

https://web.dev/urlpattern/#constructing-the-pattern

So you can do things like http{s}?://*.example.com/foo/:image.jpg. There are some cases where you need to escape URL component separators, but for most cases it just works.

@dunglas
Copy link
Author

dunglas commented Jul 23, 2021

Thank you for your detailed answer (I quoted the same part of the RFC 😅).

I'll try to add support for the current version of the spec in Mercure.

Do you know if there is a Go implementation of the current version of the spec? If it's not the case, I'll try to write one.

@dyoder
Copy link

dyoder commented Jul 23, 2021

FWIW, we implemented URL template destructuring based on a subset of RFC 6570.

One crucial aspect of this is that the destructuring is reversible. That is, other parts of the apps can reference in-application resources without knowing the structure of the URL. This reduces coupling: changes to the URL structure don't require changes elsewhere unless the parameters have changed.

I may have missed this but I didn't see any discussion of this property with respect to URL patterns.

@wanderview
Copy link
Member

Sorry, for duplicating your quote above.

As far as I know there are not any go implementations. Note, the spec is actively being written and is not complete yet. Probably the best place to look right now is the reference c++ implementation liburlpattern.

@wanderview
Copy link
Member

@dyoder Can you provide some example of reversible destructuring? I'm not sure I fully understand it.

Note, currently URLPattern does not support generating a URL or path from the pattern. Currently it only support matching. There is some discussion about adding generation in #41. That is something I would like to add in the future.

@dyoder
Copy link

dyoder commented Jul 23, 2021

@wanderview By reversibility, I just mean generation, as discussed in #41.

Throughout our applications, we don't "hardcode" the URLs, even in links. We generate them programmatically based on the routes. The routes are named, so they can be referenced logically. For example, in a blogging application, we might generate a link to the blog editor like so:

router.link({ name: "edit blog", parameters: key: "my-first-blog", nickname: "dan" })

In fact, we even do this for API resources. This preserves URL opacity.

One of the advantages of using a subset of URL Templates (6570) is that you get this for free.

@dyoder
Copy link

dyoder commented Jul 23, 2021

I'll repost over on #41. I missed that ticket or I would have posted there. :)

@freeformflow
Copy link

Another advantage is you can operate in the application with arbitrary characters, and any URLs generated from these interfaces are automatically URI encoded, so they are always safe, but transparent to the application logic. Another example of decoupling.

@wanderview
Copy link
Member

Going to close this in favor of #41 for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants