packages feed

network-uri-template-0.1.0.0: README.md

# network-uri-template

Library for parsing and expanding URI Templates, as per [RFC 6570][rfc6570].

[rfc6570]: https://datatracker.ietf.org/doc/html/rfc6570

## URI Templates

An example from the RFC:

> For example, the following URI Template includes a form-style
> parameter expression, as indicated by the "?" operator appearing
> before the variable names.
>
> ```
>   http://www.example.com/foo{?query,number}
> ```
>
> The expansion process for expressions beginning with the question-
> mark ("?") operator follows the same pattern as form-style interfaces
> on the World Wide Web:
>
> ```
>   http://www.example.com/foo{?query,number}
>                             \_____________/
>                                |
>                                |
>           For each defined variable in [ 'query', 'number' ],
>           substitute "?" if it is the first substitution or "&"
>           thereafter, followed by the variable name, '=', and the
>           variable's value.
> ```
>
> If the variables have the values
>
> ```
>   query  := "mycelium"
>   number := 100
> ```
>
> then the expansion of the above URI Template is
>
> ```
>   http://www.example.com/foo?query=mycelium&number=100
> ```
>
> Alternatively, if 'query' is undefined, then the expansion would be
>
> ```
>   http://www.example.com/foo?number=100
> ```
>
> or if both variables are undefined, then it would be
>
> ```
>   http://www.example.com/foo
> ```

For a complete description of URI Templates, consult the RFC or see our
extracted [test cases][examples].

[examples]: rfc/examples.txt

## Example

```haskell
{-# LANGUAGE OverloadedStrings #-}

module Main
  ( main
  ) where

import Prelude

import Data.Text (Text)
import Data.Text.IO qualified as T
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
import Network.URI.Template
import System.Exit (die)

main :: IO ()
main = do
  let
    vars :: Map VarName VarValue
    vars =
      Map.fromList
        [ ("query", "mycelium")
        , ("number", "100")
        ]

    template :: Text
    template = "http://www.example.com/foo{?query,number}"

    handle = either (die . templateErrorPretty) T.putStrLn

  handle $ processTemplate vars template
  -- => http://www.example.com/foo?query=mycelium&number=100

  handle $ processTemplate (Map.delete "query" vars) template
  -- => http://www.example.com/foo?number=100

  handle $ processTemplate (Map.empty) template
  -- => http://www.example.com/foo
```

## CLI

This project includes a small CLI to experiment with template expansion.

```console
network-uri-template \
  --var 'query  := "mycelium"' \
  --var 'number := "100"' \
  --var 'path   := ("foo", "bar")' \
  --var 'keys   := [("sort","asc"), ("page","2")]' \
  'http://www.example.com{/path*}/foo{?query:2,number}{&keys*}'
```

![](./cli.png)

## License

This project is licensed AGPLv3. See [COPYING](./COPYING).