URI handling

Literals

http4s is a bit more strict with handling URIs than e.g. the play http client. Instead of passing plain Strings, http4s operates on URIs. You can construct literal URI with

import org.http4s._

val uri = Uri.uri("http://http4s.org")
// uri: Uri = Uri(
//   Some(Scheme(http)),
//   Some(Authority(None, RegName(http4s.org), None)),
//   "",
//   Query(),
//   None
// )

Building URIs

Naturally, that’s not enough if you want dynamic URIs. There’s a few different ways to build URIs, you can either use a predefined URI and call methods on it, or you could use the URLTemplates.

URI

Use the methods on the uri class.

val docs = uri.withPath("/docs/0.15")
// docs: Uri = Uri(
//   Some(Scheme(http)),
//   Some(Authority(None, RegName(http4s.org), None)),
//   "/docs/0.15",
//   Query(),
//   None
// )
val docs2 = uri / "docs" / "0.15"
// docs2: Uri = Uri(
//   Some(Scheme(http)),
//   Some(Authority(None, RegName(http4s.org), None)),
//   "/docs/0.15",
//   Query(),
//   None
// )
assert(docs == docs2)

URI Template

import org.http4s.UriTemplate._

val template = UriTemplate(
  authority = Some(Uri.Authority(host = Uri.RegName("http4s.org"))),
  scheme = Some(Uri.Scheme.http),
  path = List(PathElm("docs"), PathElm("0.15"))
)
// template: UriTemplate = UriTemplate(
//   Some(Scheme(http)),
//   Some(Authority(None, RegName(http4s.org), None)),
//   List(PathElm("docs"), PathElm("0.15")),
//   List(),
//   List()
// )

template.toUriIfPossible
// res1: scala.util.Try[Uri] = Success(
//   Uri(
//     Some(Scheme(http)),
//     Some(Authority(None, RegName(http4s.org), None)),
//     "/docs/0.15",
//     Query(),
//     None
//   )
// )

Receiving URIs

URIs come in as strings from external routes or as data. Http4s provides encoders/decoders for Uri in the connector packages. If you want to build your own, use Uri.fromString.

For example one for knobs:

implicit val configuredUri = Configured[String].flatMap(s => Configured(_ => Uri.fromString(s).toOption))