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._
import org.http4s.implicits._
val uri = uri"http://http4s.org"
// uri: Uri = Uri(
//   scheme = Some(value = Scheme(value = http)),
//   authority = Some(
//     value = Authority(
//       userInfo = None,
//       host = RegName(host = http4s.org),
//       port = None
//     )
//   ),
//   path = ,
//   query = ,
//   fragment = 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(path"/docs/0.15")
val docs2 = uri / "docs" / "0.15"
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.toUriIfPossible
// res1: scala.util.Try[Uri] = Success(
//   value = Uri(
//     scheme = Some(value = Scheme(value = http)),
//     authority = Some(
//       value = Authority(
//         userInfo = None,
//         host = RegName(host = http4s.org),
//         port = None
//       )
//     ),
//     path = /docs/0.15,
//     query = ,
//     fragment = 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))