github finagle/finch 0.11.0-M1
Finch 0.11-M1

latest releases: v0.34.1, v0.34.0, v0.33.0...
8 years ago

This release is a result of fixing an old known issue when an encoder, resolved for a given type A doesn't take into an account a Content-Type of A. This is why, for example, an import io.finch.circe._ makes everything JSON.

This release also made it a new record: 24 contributors! Thank you!

Before looking closely into the changes were made, it's worth mentioning that there is now a Roadmap 1.0 available as a wiki page. It's not super clear yet how long it will take, but at least, we now have a finite list of things to-do.

Why M1?

This is just a first step (marked as M1) towards more type safety in Finch. While the solution released here is not complete, I decided to wrap up a release and let people play with initial bits, while postponing the rest of the things to M2. It's been almost 6 months since the previous release and I feel it's important to do a release (even the M-prefixed one) now, given that besides type-level content type, it also contains a number of improvements for memory and performance.

Please, note that the solution is presented here doesn't allow (doesn't compile) mixing endpoints of different content types in a single call .toService. While this sounds like a dramatic restriction, this should be viewed as a temporary step towards fully working solution that should a part of 0.11.

That said, please, consider upgrade if you only serve JSON (or anything) within your Finch server. Otherwise, would be reasonable to wait for 0.11.

Content-Type as a Type

There is now a much better way to handle content-types in Finch. A content-type is now a type-level string (see #541) and it does affect an implicit resolution of encoders, so, for example, if you ask for Encode.Text[A], and you only have Circe's encoders (JSON encoders) in the scope, your program won't compile. This a huge step towards a better utilization of Scala's type-system and capturing just a little more information in types.

Given that content-type is now a separate concept, which is neither attached to Endpoint nor Output, a way to specify it is to explicitly pass a requested content-type to a toService method call (using toServiceAs variant).

Please, note that Output.withContentType is gone since it was just a lie.

Before (broken at runtime):

// helloWorld is a text/plain endpoint that will be encoded by whatever encoder is in the scope
// (eg: if Circe is imported it will be a JSON string)
val api: Service[Request, Response] = (
  getUsers :+: postUsers :+: helloWorld
).toService

After (broken at compile time):

val api: Service[Request, Response] = (
  getUsers :+: postUsers :+: helloWorld
).toServiceAs[Application.Json]

JSON (i.e., Application.Json) is a default content-type for the to.Service call.

Charsets Make Difference

Previously, charsets set on Output don't make much of difference to the HTTP response service with Finch, rather than changing the Content-Type header. Now they are propagated to the encoder (see #610). For the sake of type-safety, a charset is now java.nio.charset.Charset, not String.

This change implies some default behaviour that should be explained. By default, a charset on Output is None so it's not copied over to the HTTP response. Although, an encoder will be using UTF-8 as a default. That said, everything will be encoded as UTF-8, but the Content-Type header won't be caring information about the charset.

Set charset either on Endpoint or Output to make it explicit (and propogated to the HTTP response).

New Endpoints

There are two new endpoints (see #606):

  • Endpoint.empty[A] that never matches
  • root: Endpoint[Request] that extracts an entire HTTP requests

Better Performance

Finch now uses Catbird's Rerunnable[A] instead of Eval[Future[A]] (see #578) and performs 20-30% better due to a reduced number of allocations.

Better Cats Integration

  1. There is now an Alternative instance for Endpoint provided out of the box (see #551).
  2. New endpoint paramsNel returns Cat's NonEmptyList (see #582)

Better Encoding

  1. It's now possible to JSON stream anything that has a JSON encoder (see #566)
  2. Anything that has a cats.Show instance now derives Encode.PlainText and so might be served as text/plain (see #561)

New Packages

  1. Support for Play JSON (see #538)
  2. Support for Spray JSON (see #568)

Better Generic Derivation

Endpoint.derive[Foo].fromParams now takes into an account optional params deriving paramOption and multi-value params deriving either params or paramsNel (see #577).

Updated Dependencies

  1. Finagle 6.35
  2. Circe 0.5.0-M2
  3. Cats 0.6
  4. Shapeless 2.3

Don't miss a new finch release

NewReleases is sending notifications on new releases.