Hi everyone,
Here’s a pitch to add RFC 6570 URI Templating support to the Foundation URL type.
Looking forward to feedback, and thanks for reading.
URI Templating
- Proposal: SF-NNNNN
- Authors: Daniel Eggert
- Review Manager: TBD
- Status: Draft
Introduction
This adds RFC 6570 URI templates to the URL
type.
While there are various kinds and levels of expansion, the core concept is that you can define a template such
as
http://example.com/~{username}/
http://example.com/dictionary/{term:1}/{term}
http://example.com/search{?q,lang}
and then expand these using named values (i.e. a dictionary) into a URL
.
The templating has a rich set of options for substituting various parts of URLs. RFC 6570 section 1.2 lists all 4 levels of increasing complexity.
Motivation
RFC 6570 provides a simple, yet powerful way to allow for variable expansion in URLs.
Imagine building applications in Swift that interact with web services or APIs. Often, these interactions rely on constructing URLs to access specific resources. Manually crafting these URLs, especially when they involve dynamic parts like user IDs or search terms, can become messy, error-prone, and hard to maintain.
URI Templates address this challenge by providing a clean and powerful way to define URL patterns with placeholders for variable data. Instead of concatenating strings and manually encoding parameters, you can define a template that clearly outlines the structure of your URL, highlighting the parts that will change based on your application's logic.
An example use case is the server sending a template string to a client, to inform the client how to construct URLs for accessing resources.
Proposed solution
let template = URL.Template("http://www.example.com/foo{?query,number}")
let url = template?.makeURL(variables: [
"query": "bar baz",
"number": "234",
])
The RFC 6570 template gets parsed as part of the URL.Template(_:)
initializer. It will return nil
if the passed in string is not a valid template.
The Template
can then be expanded with _variables _ to create a URL:
extension URL.Template {
public makeURL(
variables: [URL.Template.VariableName: URL.Template.Value]
) -> URL?
}
Read on
You can read the full pitch including the detailed design in the pull request on the swift-foundation repository.