Finch.io v0.27.0 Release Notes
Release Date: 2019-01-13 // over 5 years ago-
๐ This new release is featuring fs2 integration as well fully reworked streaming support, allowing for easier testing of streaming endpoints.
๐ FS2 Support
๐ #1042 adds fs2 support in Finch (thanks @sergeykolbasov). As of 0.27, it's now possible to receive and send JSON (or pretty much any arbitrary) streams using fs2's
Stream
type. The new API entry point,bodyStream
, allows to construct streaming endpoints with the requested stream type,Enumerator
(iteratee) orStream
(fs2).scala\> import fs2.Stream, io.finch.\_, io.finch.catsEffect.\_, io.finch.fs2.\_scala\> val bin = binaryBodyStream[Stream] // raw byte-array streambin: Endpoint[IO, fs2.Stream[IO, Array[Byte]]] = binaryBodyStream scala\> val str = stringBodyStream[Stream] // stream of stringsstr: Endpoint[IO, fs2.Stream[IO, String]] = stringBodyStream
Similarly, accepting a stream of JSON object is possible via
bodyStream
orjsonBodyStream
endpoints.scala\> import fs2.Stream, io.finch.\_, io.finch.catsEffect.\_, io.finch.fs2.\_scala\> import io.finch.circe.\_, io.circe.generic.auto.\_scala\> case class Foo(s: String) defined class Fooscala\> val foos = bodyStream[Stream, Foo, Application.Json] foos: Endpoint[IO,f s2.Stream[IO, Foo]] = bodyStream scala\> val foos = jsonBodyStream[Stream, Foo] foos: Endpoint[IO, fs2.Stream[IO, Foo]] = bodyStream
๐ฐ Serving streaming bodies is no different from serving fully-buffered payloads, just return
Stream
(fs2) orEnumerator
from an endpoint.scala\> import fs2.Stream, cats.effect.IO, io.finch.\_, io.finch.catsEffect.\_, io.finch.fs2.\_scala\> import io.finch.circe.\_, io.circe.generic.auto.\_scala\> case class Foo(s: String) defined class Fooscala\> val foos = Endpoint[IO].const(Stream[IO, Foo](Foo("bar"))) foos: Endpoint[IO, fs2.Stream[IO, Foo]] = io.finch.Endpoint$$anon$34@5428e82e scala\> foos.toServiceAs[Application.Json] res1: Service[Request, Response] = io.finch.ToService$$anon$4$$anon$2
โ Testing Streaming Endpoints
๐ #1056 enables users to construct
Input
instances with streaming bodies (non fully buffered). At this point, both fs2 and iteratee streams are supported.import io.finch.\_, io.finch.iteratee.\_, io.interatee.Enumerator, cats.effect.IOval i = Input .post("/") .withBody[Text.Plain](Enumerator.enumerate[IO, String]("foo", "bar", "baz"))
Creating an
Input
out of a JSON stream is also possible:import io.finch.\_, io.finch.iteratee.\_, io.interatee.Enumerator, cats.effect.IOimport io.finch.circe.\_, io.circe.generic.auto.\_case class Foo(s: String)val i = Input .post("/") .withBody[Application.Json](Enumerator.enumerate[IO, Foo](Foo("foo"), Foo("bar")))
Switching between iteratee and fs2 is as easy as replacing
io.finch.iteratee._
import withio.finch.fs2._
.โก๏ธ Dependency Updates