Finch 0.23
This new Finch release, while matching Finagle 18.8, comes with several quite exciting improvements.
Multiple Decoders for Bodies
We've been asked if it's possible to specify multiple decoders (in a sense of or
application) to a single body
endpoint. Similar how users can serve multiple content-types based on the Accept
header value, they now can resolve multiple decoders at compile-time and dispatch to an appropriate decoder at runtime when a request with the Content-Type
header arrives (see #966 for implementation details; thanks @sergeykolbasov).
scala> import io.finch._, com.twitter.util._, com.twitter.io.Buf, shapeless._
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class Foo(s: String)
object Foo {
implicit val d1 = Decode.instance[Foo, Text.Plain]((_, _) => Return(Foo("text")))
implicit val d2 = Decode.instance[Foo, Text.Html]((_, _) => Return(Foo("html")))
}
^D
scala> val foo = body[Foo, Text.Plain :+: Text.Html :+: CNil]
foo: io.finch.Endpoint[Foo] = body
scala> foo(Input.post("/").withBody[Text.Plain](Buf.Utf8("foo"))).awaitValueUnsafe()
res5: Option[Foo] = Some(Foo(text))
scala> foo(Input.post("/").withBody[Text.Html](Buf.Utf8("foo"))).awaitValueUnsafe()
res6: Option[Foo] = Some(Foo(html))
Arrows instead of Rerunnables
We've been experimenting with Trane Arrows as a drop-in replacement for Finch's underlying effect, Rerunnable
. The results are quite uplifting considering the performance improvements gained without visible API changes.
Here is a sneak peek into the performance improvements (see #964 for more details; thanks @erikwj).
BEFORE (Rerunnable)
[info] Benchmark Mode Cnt Score Error Units
[info] ProductBenchmark.bothMatched avgt 10 984.884 ± 35.849 ns/op
[info] ProductBenchmark.bothMatched:·gc.alloc.rate.norm avgt 10 1472.000 ± 0.001 B/op
AFTER (Arrow/Task)
[info] ProductBenchmark.bothMatched avgt 10 361.867 ± 8.955 ns/op
[info] ProductBenchmark.bothMatched:·gc.alloc.rate.norm avgt 10 712.000 ± 12.749 B/op
We published Finch depending on Arrows (instead of Rerunnable
s) under its own artifact for now for the sake of keeping the standard version unchanged. We are aiming to collect more feedback from users before we decide to adopt/not adopt. Use the following dependency (finch-arrows-x
instead of finch-x
) to experiment with Arrows (no source changes required) and let us know what do you think in #968.
libraryDependencies ++= Seq(
"com.github.finagle" %% "finch-arrows-core" % "0.23.0",
"com.github.finagle" %% "finch-arrows-circe" % "0.23.0",
)
Other Changes
- New cookbook recipe on how to use Finagle clients (see #962, thanks @erikwj)
- Bug fix for
build.sbt
so finch-refined is actually published now (see #969, thanks @rider-yi) - The user guide has been updated with examples on how to encode accumulated errors from Circe (see #970, thanks @rpless)
- finch-json4s was extracted into its own project (see #971 and https://github.com/finch/finch-json4s).