Skip to main content

kebs-http4s / kebs-http4s-stir

Path and query parameter codecs for http4s and http4s-stir.

Setup

// http4s
libraryDependencies += "pl.iterators" %% "kebs-http4s" % kebsVersion

// http4s-stir (Akka HTTP-style directives for http4s)
libraryDependencies += "pl.iterators" %% "kebs-http4s-stir" % kebsVersion

Both modules also publish Scala.js artifacts.

kebs-http4s

Usage (Scala 3)

import pl.iterators.kebs.http4s.{given, *}
import pl.iterators.kebs.opaque.Opaque
import pl.iterators.kebs.enums.KebsEnum
import pl.iterators.kebs.instances.KebsInstances._

opaque type Age = Int
object Age extends Opaque[Age, Int]

case class UserId(id: UUID)

enum Color { case Red, Blue, Green }

val routes = HttpRoutes.of[IO] {
case GET -> Root / "user" / WrappedUUID[UserId](userId) => ...
case GET -> Root / "age" / WrappedInt[Age](age) => ...
case GET -> Root / "color" / EnumString[Color](color) => ...
case GET -> Root / "currency" / InstanceString[Currency](curr) => ...
case GET -> Root / "day" / InstanceInt[DayOfWeek](dow) => ...
case GET -> Root / "ts" / InstanceLong[Instant](ts) => ...
}

Path segment matchers

MatcherExtractsVia
WrappedInt[T]Int path segment → TValueClassLike[T, Int]
WrappedLong[T]Long path segment → TValueClassLike[T, Long]
WrappedString[T]String path segment → TValueClassLike[T, String]
WrappedUUID[T]UUID path segment → TValueClassLike[T, UUID]
InstanceString[T]String path segment → TInstanceConverter[T, String]
InstanceInt[T]Int path segment → TInstanceConverter[T, Int]
InstanceLong[T]Long path segment → TInstanceConverter[T, Long]
InstanceUUID[T]UUID path segment → TInstanceConverter[T, UUID]
EnumString[T]String path segment → TEnumLike[T]

QueryParamDecoder derivation

The same import also provides automatic QueryParamDecoder instances for:

  • Any type with a ValueClassLike (value classes, opaque types, tagged types)
  • Any type with an InstanceConverter (java.time types, UUID, etc.)
  • Any type with an EnumLike
object AgeQueryParamMatcher extends QueryParamDecoderMatcher[Age]("age")
object ColorQueryParamMatcher extends ValidatingQueryParamDecoderMatcher[Color]("color")
object OptionalYearMatcher extends OptionalQueryParamDecoderMatcher[Year]("year")

val routes = HttpRoutes.of[IO] {
case GET -> Root / "query" :? AgeQueryParamMatcher(age) +& ColorQueryParamMatcher(color) => ...
}

Scala 2

On Scala 2, use KebsEnumeratum instead of KebsEnum, and tagged types (@@) instead of opaque types. See the Scala 2 tests for examples.

kebs-http4s-stir

http4s-stir provides Akka HTTP-style directives for http4s. Kebs integrates via two packages:

Unmarshallers

import pl.iterators.kebs.http4sstir.unmarshallers.KebsHttp4sStirUnmarshallers
// or: import pl.iterators.kebs.http4sstir.unmarshallers._

Provides FromStringUnmarshaller for value classes, enums, value enums, and instance types. Works with parameters, formFields, and entity directives:

parameters("sortBy".as[Column], "order".as[SortOrder], "offset".as[Offset]) { ... }
formFields("yearMonth".as[YearMonth]) { ... }

Path matchers

import pl.iterators.kebs.http4sstir.matchers.KebsHttp4sStirMatchers
// or: import pl.iterators.kebs.http4sstir.matchers._

Same extension methods as Akka/Pekko HTTP matchers: .as[T], .to[T], .asEnum[T], .asValueEnum[T], and chaining (.to[URI].as[TaggedUri]).