Finch is a simple library that provides an immutable layer of functions and types on top of Finagle for writing lightweight and composable HTTP services in a functional settings.
The following example creates an HTTP server (powered by Finagle) that serves the only endpoint POST /time
. This
endpoint takes a Locale
instance represented as JSON in request body and returns a current Time
for this locale.
build.sbt:
libraryDependencies ++= Seq(
"com.github.finagle" %% "finch-core" % "0.9.2",
"com.github.finagle" %% "finch-circe" % "0.9.2",
"io.circe" %% "circe-generic" % "0.2.1"
)
Main.scala:
import com.twitter.finagle.Http
import com.twitter.util.Await
import io.finch._
import io.finch.request._
import io.finch.circe._
import io.circe.generic.auto._
object Main extends App {
case class Locale(language: String, country: String)
case class Time(locale: Locale, time: String)
def currentTime(l: java.util.Locale): String =
java.util.Calendar.getInstance(l).getTime.toString
val time: Endpoint[Time] =
post("time" ? body.as[Locale]) { l: Locale =>
Ok(Time(l, currentTime(new java.util.Locale(l.language, l.country))))
}
Await.ready(Http.server.serve(":8081", time.toService))
}
@mandubian on Twitter:
I think there is clearly room for great improvements using pure FP in Scala for HTTP API & #Finch is clearly a good candidate.
I'm currently working on a project using Finch (with Circe to serialize my case classes to JSON without any boilerplate code-- in fact, besides the import statements, I don't have to do anything to transform my results to JSON) and am extremely impressed. There are still a few things in flux with Finch, but I'd recommend giving it a look.
@arnarthor on Gitter:
I am currently re-writing a NodeJS service in Finch and the code is so much cleaner and readable and about two thirds the amount of lines. Really love this.
- Finch: Your REST API as a Monad by @vkostyukov on Dec 2015
- On the history of Finch by @vkostyukov on Apr 2015
- Some possible features for Finch @travisbrown on Apr 2015