All Versions
Latest Version
Avg Release Cycle
56 days
Latest Release
114 days ago

Changelog History

  • v0.32.1

    March 11, 2020

    Hello Scala 2.13, bye 2.11

    🚀 Long-awaited release for Scala 2.13 has finally arrived. Thanks for your patience as well as for all the efforts the community has made to update Finagle to 2.13.

    ⬇️ We also drop the support for Scala 2.11, as some of the dependencies aren't available for that version.

    🚀 Last release of finchx artifacts. Long live the finch

    🚀 This release is expected to be the last one for finchx prefixed artifacts. Starting from the next update we're going to decommission the Future-based finch artifacts and replace it with polymorphic one.
    ⚡️ Effectively, it means that no finchx artifacts will be updated and you would need to update the dependency by dropping the x letter.

    📚 To ensure the best developer experience we're going to groom existing documentation to make it up to date with all the exciting changes and capabilities of Finch.

    🚀 Release notes

    • ⚡️ Updated all the core dependencies to their latest versions
    • ➕ Add Endpoint.coproductAll for summing a list of endpoints (#1178, kudos to @joroKr21)
  • v0.32.0

    March 10, 2020

    👀 See 0.32.1

  • v0.31.0

    September 05, 2019
    • ⚡️ Update Finagle to 19.8.0 and cats-effect to 1.4.0.
    • 🐛 Bug fix : Exceptions occurred outside of F[_] context in Endpoint.mapOutput are properly handled. This was an annoying issue for those who work with ZIO. Thanks @Phill101 (Detais: #1142)
  • v0.30.0

    August 19, 2019

    🚀 This is a release of Finch with Finagle 19.6.0.

    🚀 In addition to version bumps of many libraries, this release has the following:

    • 🗄 Removal of the deprecated transformOutput
  • v0.29.0

    May 18, 2019

    🚀 A release for Finagle 19.4, the first release without Netty 3 on the classpath!

    In addition to version bumps, here are the notable changes:

    • 👀 Streams are now cancellable if your effect supports it (see #1082 (thanks to @joroKr21)
    • 🛠 Bugfix in how charsets are fetched from requests (see #1104)
  • v0.28.0

    February 27, 2019

    🚀 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 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($$$Lambda$2999/1785722147@b53898c) finch@ val finale = authFilter.andThen(compiled) finale: Kleisli[IO, Request, (Trace, Either[Throwable, com.twitter.finagle.http.Response])] = Kleisli($$$Lambda$2999/1785722147@7c51944f) finch@ val service = Endpoint.toService(finale) service: com.twitter.finagle.Service[Request, com.twitter.finagle.http.Response] = ToService(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 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.

  • v0.27.0

    January 13, 2019

    🚀 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) or Stream (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 or jsonBodyStream endpoints.

    scala\> import fs2.Stream, io.finch.\_, io.finch.catsEffect.\_, io.finch.fs2.\_scala\> import io.finch.circe.\_,\_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) or Enumerator from an endpoint.

    scala\> import fs2.Stream, cats.effect.IO, io.finch.\_, io.finch.catsEffect.\_, io.finch.fs2.\_scala\> import io.finch.circe.\_,\_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.\_,\_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 with io.finch.fs2._.

    ⚡️ Dependency Updates

  • v0.26.1

    December 05, 2018

    🛠 🐞Bugfix release:

    • 👻 Endpoint.rescue was incorretly throwing MatchError if the exception inside of an effect was not defined for the given partitial function. The correct behavior is to re-raise the exception. This bug affected only finchx- modules. #1048
  • v0.26.0

    November 15, 2018

    🚀 finch-* Release (Twitter Futures)

    • ⚡️ We have updated to Twitter Utils and Finagle 18.11.0

    🚀 finchx-* Release (Cats Effect)

    ⚡️ Backwards Compatibility Updates

    👀 One of the biggest concerns with moving to cats-effect in 0.25 was the lack of backwards compatibility with existing Future-based endpoints (both Scala and Twitter implementations). This version eases that transition by adding support for both Scala and Twitter futures in the Mapper. See #1016 for more details.

    scala\> import io.finch.\_, io.finch.catsEffect.\_scala\> import com.twitter.util.Futurescala\> val foo = get(pathEmpty) { Future.value(Ok("foo")) } \<console\>:18: warning: method mapperFromFutureOutputValue in trait HighPriorityMapperConversions is deprecated (since 0.25.0): com.twitter.util.Future use is deprecated in Endpoints. Consider to use cats-effect compatible effect val foo = get(pathEmpty) { Future.value(Ok("foo")) } ^ foo: io.finch.Endpoint[cats.effect.IO,String] = GET /

    NOTE: The foo endpoint is still structured as Endpoint[cats.effect.IO, String]. Both Scala and Twitter Futures are converted to IO when endpoints are mapped.

    👍 Stewarding a better Environment

    🚀 In the past, we've gotten a fair number of Github issues and Gitter messages about getting dependencies up to date. With this release we have enabled Scala Steward which makes PRs to update versions of dependencies. A huge thanks to @fthomas for creating this tool and to @travisbrown for adding this to our main repository. We are looking into adding it into our other repositories from the Finch Org.

    🍱 Serving Static Assets

    👀 We're not about telling you not to do something with Finch, only that you can do things with Finch. In this vein, you probably shouldn't serve static assets from the classpath or a file from Finch (or really any HTTP library that isn't designed for serving static assets). But we've added Endpoint.classpathAsset and Endpoint.filesystemAssert that let you do just that. Please, try not to use this in a production environment as it will never match the throughput of what static server. See #1017 for more details.

    scala\> import io.finch.\_, io.finch.catsEffect, scala\> import cats.effect.{IO, ContextShift} scala\> import scala.concurrent.ExecutionContextscala\> implicit val S: ContextShift[IO] = IO.contextShift( cats.effect.ContextShift[cats.effect.IO] = cats.effect.internals.IOContextShift@641d5285 scala\> val index = classpathAsset("/index.html") index: io.finch.Endpoint[cats.effect.IO,] = GET /index.html :: io.finch.endpoint.package$FromInputStream@63905eda scala\> index.toServiceAs[Text.Html] res3: com.twitter.finagle.Service[com.twitter.finagle.http.Request,com.twitter.finagle.http.Response] = io.finch.ToService$$anon$4$$anon$2


    We now have a basic gitter8 template to get new projects started fast (thanks to @vkostyukov). Just run sbt new finch/finch.g8 to get started.

    Other Changes

    • 👀 Endpoint now has an pathEmpty method which matches an empty path string (see #1015)
    • ⚡️ We have updated to Twitter Utils and Finagle 18.11.0 (see #1033)
    • 👀 Our version badge now points at Scala Index (see #1010)
    • 👀 Endpoint.pathAny now properly captures the matched Trace (see #1017)
    • 👀 We refined our Todo App example with the new shiny UI and tests (see #1020)
  • v0.25.0

    October 21, 2018

    🚀 Our anniversary 50th release brings a lot of exciting changes. The biggest news is starting with 0.25 (this release) Finch is now completely agnostic to the underlying effect type (was Twitter Future before).

    Polymorphic Endpoints

    This is, perhaps, the biggest change in Finch since introduction of Endpoint couple of years back. Locking our core APIs to a particular effect type (Twitter Future) never felt right yet, surely, was a reasonable thing to do at first. As Finch's API matured, we figured the major source of complains from our users was about this hard dependency to a Twitter's stack (think Twitter Util's).

    🚀 With the 1.0 release of cats-effect, it became clear that Finch's path towards better interoperability with the rest of typelevel libraries (think Cats-based libraries) was adopting Effect type classes in the Endpoint API.

    Long story short Endpoint[A] now becomes Endpoint[F[_], A] where F[_] is anything that has an cats.effect.Effect instance (think ZIO, Monix Task, Cats IO, Catbird Rerunnable, etc). This heroic effort was driven by @sergeykolbasov in #979.

    🛠 This sounds scary at least - a LOT of API changes. To mitigate the impact we keep releasing normal Finch artifacts (Twitter Futures) under a previous name: finch-*. This means you don't really have to migrate to a new endpoint API just now. The current plan is to keep supporting a previous version of Finch API for some time (at least 6 months) but keep its branch under feature freeze (commit only bug-fixes and dependency bumps).

    If you're feeling adventurous, you can jump into polymorphic endpoints now by depending on finchx-* artifacts instead.

    libraryDependencies ++= Seq( "com.github.finagle" %% "finchx-core" % "0.25.0", "com.github.finagle" %% "finchx-circe" % "0.25.0", )

    👀 There several ways how to instantiate polymorphic endpoints (see #988). Perhaps, the most standard way is via importing io.finch.catsEffect._ EndpointModule (in case if you prefer Cats IO as your effect type).

    import io.finch.\_import io.finch.catsEffect.\_val p: Endpoint[IO, Int] = param[Int]("foo")

    You can also specify the F[_] type constructor explicitly should you prefer other effect implementation.

    import io.finch.\_val p: Endpoint[MyIO, Int] = Endpoint[MyIO].param[Int]("foo")

    Or via instantiating an EndpointModule for your effect instance.

    import io.finch.\_object myIO extends Endpoint.Module[MyIO]import myIO.\_val p: Endpoint[MyIO, Int] = param[Int]("foo")

    Notable Changes Accommodating cats-effect Integration

    • 📦 Syntax Package became obsolete (do not need to import it) as we can now derive syntax based on Effect instance.
    • As we're no longer depending on Twitter Futures, other Twitter APIs (Duration, Try) have been migrated to their Scala's counterparts.

    🐎 Performance

    🚀 We did some initial testing of new endpoints and the outcome looks optimistic. Essentially, we're observing similar performance gains as we did with Trane Arrows couple of releases back.

    🚀 Auto Releases

    🚀 Inspired by how Trane Arrows's build is setup, @arron-green kicked in a new releasing machinery for Finch. Now we can cut releases via a single commit that changes the version.sbt file (see #995 and #1000 for more details). Everything is automated and requires no human supervision or interaction. This very release was performed this way.

    🚀 This is quite an exciting and very necessary improvement as now any Finch maintainer (a person with a push access to a repository) can cut releases.

    Other Changes

    • 👀 Finagle is bumped to 18.10 (see #1007)
    • 👀 Circe is bumped to 0.10 (see #991)