Finch.io v0.28.0 Release Notes

Release Date: 2019-02-27 // about 5 years ago
  • ๐Ÿš€ This release introduces new functionality to build a middleware of your HTTP service.

    Kleisli composition

    Instead of converting Endpoint straight into Service[Request, Response], there is now an option to compile it first into Kleisli[F[_], Request, (Trace, Either[Throwable, Response])] data type (or Endpoint.Compiled[F] as a type alias). It allows to replace most of the Finagle filters with Kleisli composition that is also effect-aware:

    finch@ import cats.effect.IOimport cats.effect.IOfinch@ import cats.data.Kleisliimport cats.data.Kleislifinch@ import io.finch.\_import io.finch.\_finch@ import io.finch.catsEffect.\_import io.finch.catsEffect.\_finch@ val endpoint = get("hello") { Ok("world") } endpoint: Endpoint[IO, String] = GET /hello finch@ val compiled = Bootstrap.serve[Text.Plain](endpoint).compile compiled: Endpoint.Compiled[IO] = Kleisli(io.finch.Compile$$anon$2$$Lambda$2951/1251806319@7dccca17) finch@ val authFilter = Kleisli.ask[IO, Request].andThen { req =\>if(req.authorization.isEmpty) IO.raiseError(new IllegalStateException()) else IO.pure(req) } authFilter: Kleisli[IO, Request, Request] = Kleisli(cats.data.Kleisli$$$Lambda$2999/1785722147@b53898c) finch@ val finale = authFilter.andThen(compiled) finale: Kleisli[IO, Request, (Trace, Either[Throwable, com.twitter.finagle.http.Response])] = Kleisli(cats.data.Kleisli$$$Lambda$2999/1785722147@7c51944f) finch@ val service = Endpoint.toService(finale) service: com.twitter.finagle.Service[Request, com.twitter.finagle.http.Response] = ToService(Kleisli(cats.data.Kleisli$$$Lambda$2999/1785722147@7c51944f)) finch@ service(Request("/hello")) res38: com.twitter.util.Future[com.twitter.finagle.http.Response] = Promise@471126862(state=Done(Throw(java.lang.IllegalStateException))) finch@ val req = Request("/hello") req: Request = Request("GET /hello", from 0.0.0.0/0.0.0.0:0) finch@ req.authorization = "user:password"finch@ service(req) res41: com.twitter.util.Future[com.twitter.finagle.http.Response] = Promise@1914269162(state=Done(Return(Response("HTTP/1.1 Status(200)"))))
    

    ๐Ÿ— Finch will do its best to prevent F[_] from having an exception inside of compiled Endpoint and have it inside of the Either. Check out proper example how to build and compose filters together.

    ๐Ÿ”จ Endpoint.transformF and type classes refactoring

    ๐Ÿ“š We've made a small refactoring over the Finch codebase to use as least powerful abstractions for effect F[_] as possible. Now, in most of the places it's enough to have Sync or Async type classes available to build endpoints. It enables the use of things like StateT, Kleisli, and WriterT as your effect type, thus propagating the data down the line using the effect. More examples and documentation on this later.

    ๐Ÿ—„ AsyncStream deprecation

    ๐Ÿ—„ asyncBody deprecation cycle is over, consider to use fs2 or iteratee as a replacement in case if you need a streaming. Both of them are supported by corresponding Finch modules. Here is the simple example of how to use one.
    Also, finch-sse was removed as a separate module. Related code moved to the core and finch-fs2 & finch-iteratee modules.

    Join our community

    ๐Ÿ†“ If you have any questions or ideas, feel free to address them in issues or join our gitter channel.