Also available in: Español · Português · Français · العربية
URI template expander: RFC 6570, all four levels
Paste a template and some values, get the URL, and see exactly which piece of the template produced which piece of the result.
What is a URI template?
A URI template is a URL with holes in it. A name in braces in the middle of a path is a hole; so is a brace-wrapped list at the end beginning with a question mark, which turns into a query string. Give the template a set of values and it becomes a real URL. The format is RFC 6570, and it is more capable than string substitution: it knows the difference between a path segment and a query parameter, it escapes each of them by the right rules, and it can turn one list into several repeated parameters.
You have almost certainly received one without being told. Ask the GitHub API for anything and the response is full of them — the root document alone hands back fields ending in a braced gist id and a braced since-and-page pair. That is the point of the format: a server describes the shape of a URL space once, and a client fills in the blanks, instead of every client hard-coding string concatenation and getting the escaping wrong.
There are four levels. Level 1 is plain substitution. Level 2 adds the two expansions that let a value carry slashes and other reserved characters through untouched. Level 3 adds the path, query and fragment operators, and lets one expression name several variables. Level 4 adds the two value modifiers — take the first few characters of a value, or explode a list into repeated parameters. A real GitHub template stops at level 3, which is worth knowing, because level 4 is where implementations start to disagree.
How to use it
- Paste a template. Anything in braces is an expression; everything else is copied through, with characters a URL cannot carry percent-encoded on the way. The sample buttons cover a real API template, a repeated query parameter, reserved expansion and a prefix.
- Give it some values as JSON. A string is a plain value, an array is a list, an object is a set of name and value pairs. Leaving a name out is not an error — an undefined variable expands to nothing, which is how optional query parameters work.
- Read the breakdown. Under the result there is a row for every piece of the template and the piece of the URL it produced. That is where the escaping rules become visible, and where a mistake shows up as a row that contributed itself, unchanged.
A broken template still gives you a URL
Write a template with a mistake in it and this tool will not stop. It will expand everything it can, copy the broken part through exactly as you wrote it, and tell you what is wrong underneath. That is not leniency, it is the specification: when a processor hits a bad expression, the unprocessed part should be copied to the result unexpanded and processing should continue, and the caller should be told the location and type of the error. The RFC describes the outcome as a result intended for diagnostic use.
There is a reason a hypermedia format is written that way. The templates you expand often arrive from somewhere else, in an API response you did not write, and a client that throws on a field it did not expect is worse than one that carries on and reports the problem. The two failure modes are even deliberately different: a bad character outside an expression stops the scan dead, so everything after it — including expressions that would otherwise have worked — is left exactly as written. Try the mistake sample and watch which parts still expand.
The catch is that almost nothing implements the reporting half. Two published expanders were measured while this page was built: given the thirty-six templates the specification's own test suite marks as invalid, neither threw and neither returned any error indication. Both handed back a plausible-looking URL every time, and on five of the thirty-six they handed back different URLs from each other. If you have ever wondered why a malformed template produced a wrong request instead of a stack trace, that is why.
A specification with no prohibitions
RFC 6570 contains no MUST NOT and no SHOULD NOT — not one, outside the boilerplate paragraph that lists what those words mean. In the whole document there are four MUSTs, seven SHOULDs and three MAYs. That is unusual, and it explains the rest: when the error handling is written as a SHOULD, implementations are conformant whether they follow it or not, and they mostly do not.
It also has one place where it contradicts itself, which this tool follows the test suite on rather than the grammar. The rule for what may appear outside an expression excludes the apostrophe, and lists it by name among the forbidden characters. But an apostrophe is legal in a URL, the section immediately above says characters legal in a URL are copied through, and the official conformance suite contains a case requiring an apostrophe to survive — filed under the number of the very section whose grammar forbids it. The suite wins here.
One more rule worth knowing because it is invisible in the template. Asking for the first character of a value counts characters, not the units a programming language happens to store them in. The specification says so twice and gives the reason: it is there to stop an implementation cutting a character in half. Ask both measured libraries for the first character of a musical clef sign and neither returns it — both throw, because slicing a JavaScript string at position one splits that character into two halves and leaves an invalid fragment behind.
What this tool will not do
It does not go the other way. Pulling the values back out of a finished URL — matching, rather than expanding — is a genuinely harder problem, and the RFC declines it in its own words: variable matching, it says, only works well when the expressions are delimited by the ends of the URL or by characters that cannot appear in the expansion, and in general regular expressions are better suited to the job. A template ending in two adjacent variables with nothing between them has no single right answer.
It does not fetch anything or check that the URL it produces exists. A template that expands to a perfectly formed address for a resource nobody ever created looks exactly like one that works. Worth remembering in the other direction too, in the specification's own words: a template is not a URI. It does not identify a resource, it is not parsed as one, and it should not be put anywhere a URI is expected until something has expanded it — which is why an API that serves templates gives them field names of their own rather than mixing them in with finished links.
The results here are checked against the specification's own conformance suite rather than against another library — all 117 positive cases, and all 36 invalid templates reported as invalid rather than silently expanded. Agreeing with another implementation would only show that two people made the same choices.
Why is it free?
Expanding a template is string processing, and it happens in your browser. There is no server in the path, so there is nothing to meter and no account to create.
Nothing is uploaded. The template you paste and the values you type stay in this tab.