This release introduces a bunch of neat features as well as some housekeeping cleanups.
Breaking API Changes
finch-auth
has been removed from the project (see new feature "Basic HTTP Auth")- Type aliases
io.finch.HttpRequest
andio.finch.HttpResponse
were removed (use Finagle's types instead) - The
flatMap
method onRouter
has been replaced withap
Deprecated API
- All the old-style endpoints are deprecated:
io.finch.Endpoint
andio.finch.Endpoint
in favour of coproduct routers - The custom request types are also deprecated (see this note)
- All the implicit classes (the bang! operator) on top of
Service
andFilter
are deprecated
New Packages
finch-circe
- enables circe support in Finchpetstore
- the brand new implementation of the popular demo project
New Features
Basic HTTP Auth
Use the following API in order to enable Basic HTTP Auth on the given Router
.
val r: Router[String] = Router.value("protected")
val authR: Router[String] = basicAuth("username", "password")(r)
Smart Router
s Composition
When compositing two coproduct Router
s the yielded Router
will always be flattened.
val r1: RequestReader[Int :+: String :+: CNil] = Router.value(10) :+: Router.value("s1")
val r2: Router[Boolean :+: String :+: CNil] = Router.value(true) :+: Router.value("s2")
val r3: Router[Int :+: String :+: Boolean :+: String :+: CNil] = r1 :+: r2
Compose RequestReader
s and Router
s
Since 0.8.0 it's possible to compose Router
and RequestReader
together with the ?
combinator.
val r1: RequestReader[Int :: String :: HNil] = param("a").as[Int] :: param("b")
val r2: Router[Boolean] = Router.value(true)
val r3: Router[Boolean :: Int :: String :: HNil] = r2 ? r1
Method Matchers
It's now recommended to use new API for matching the HTTP methods.
// Before
val r1: Router0 = Get / "users"
// After
val r2: Router0 = get("users")
Router
Mapper
There is a new API for mapping routers to either functions A => B
or A => Future[B]
. Use an apply
method on Router
instead of methods />>
and >
, which are going to be deprecated in 0.9.0.
val r1: Router[Int] = get("users" / int) { id: Int => id * 42 }
val r2: Router[String] = get("hello") { Future.value("Hello, World!") }
There is just one downside of this feature: you have to always specify all the types in the function you're passing.
Tail Extractors
For each route extractor (i.e., int
, string
), there is now a corresponding tail extractor that extracts a Seq[A]
from the tail of the current route.
// will match "/users/10/20/30" and extract Seq(10, 20, 30)
val r: Router[Seq[Int]] = "users" / ints