The Finch library provides an immutable layer of functions and types atop of Finagle for writing lightweight HTTP services. It roughly contains three packages: io.finch.route, io.finch.request, io.finch.response, which correspond to three simple steps to a robust REST/HTTP API:
The Router abstraction routes the requests depending on their path and method information. Router
combinator provides a bunch of predefined routers handling separated parts of a route. Router
s might be composed with
either /
(flatMap
) or />
(map
) operator. There is also |
(orElse
) operator that combines two routers in
terms of the inclusive or operator.
val router: Endpoint[HttpRequest, HttpResponse] = Get / ("users" | "user") / int /> GetUser
The RequestReader abstraction is responsible for reading any details form the HTTP request.
RequestReader
is composable in both ways: via the monadic API (using the for-comprehension, i.e., flatMap
/map
) and
via the applicative API (using the ~
operator). These approaches define an unlimited number of readers out the plenty
of predefined ones.
val pagination: RequestReader[(Int, Int)] =
paramOption("offset").as[Int] ~ paramOption("limit").as[Int] map {
case offset ~ limit => (offset.getOrElse(0), limit.getOrElse(100))
}
The ResponseBuilder abstraction provides a convenient way of building the HTTP responses
of any type. In fact, ResponseBuilder
is a function that takes some content and builds an HTTP response of a type
depending on a content. There are plenty of predefined builders that might be used directly.
val ok: HttpResponse = Ok("Hello, world!") // plain/text HTTP response with status code 200