Last week ScalaTimes presented Creating a TODO application using Akka HTTP and Slick, which encouraged myself to do the same type of starting tutorial in Finch.
Finch is a project written by people working mostly on Twitter and it is a TypeLevel incubator. What I like the most about Finch is its simplicity by using pure functional programming constructs and highly efficient libraries underneath.
Personally, I have used Finch in various small projects and once in a very serious project / environment. I always found it very easy and simplistic even though it is a very capable library.
Finch is fast, just look at How Fast is Finch? You will discover that it is the second faster HTTP library written in Scala.
Let’s focus now how to create a simple Rest API using Finch.
Our build.sbt file looks like follow:
We are only adding the the Finch libraries and Circe for JSON serialization/deserialization.
Now, we need to create our first endpoint to be served.
Let’s start by something very simplistic and then grow from there. First, we can define a
Endpoint is, in my opinion, the most important construct we are going to find in Finch.
The idea behind
Endpoint is that it represent a serie of transformations as follows:
We get a
Request and transform it into some type
A. Then we apply some business logic to the input in an asynchronous matter just to finalize with another transformation into the desired
In our example, our
Endpoint is a
get which URL is
hello and the business logic to be applied is just returning
hello to you!.
Now, we need to run the server and expose the
hello to be used.
We have only created an application that we can be executed, and we have create a
server to connect to
localhost:8080 then it serves the
Endpoint as a Finagle Service.
We can run the application by doing
sbt run or
java -jar <the application.jar>. Once running we can send a request to the endpoint using our terminal:
http localhost:8080/hello and we will get back:
For this example, we are going to use a storage abstraction that can be implemented in multiple ways, in particular we can create one that talks to an in-memory datastore.
Item is the type of objects we are going to be sending and receiving to our API and Storage is the one in charge of saving / retrieving them.
Our in-memory implementation is as simple as this.
Our first endpoint will be
todos that retrieves all items available in the storage.
We can see how simple that is! It just does a
storage.getAll call. This endpoint will respond to
GET /todos URL in our server.
Now we can define a new endpoint to add todos that will respond at
This one is a little more interesting to look at. Because it is a
POST we need to extract the
Item from the body of the message. However, there is a gotcha, the
Item cannot be created without an
UUID and that is what the
postTodo function does. In other words, we extract the
taskName from the
POST message body and create an
Item object with it and a random
The idea is that you don’t need to have a different
Item model without the id to be sent on the requests.
storage.add(item) does not really care about the id, it just add a new
Item to the storage and returns the recently created one (it has its own new id).
Item has been added, we return the recently created one.
We can test it from our terminal by doing
Retrieving a particular
Item is an easy task. We only need the id and then we can ask for the
storage to get it for us.
We can test it by doing:
Which returns the same todo we inserted before.
Notice that if the item is not in the storage,
.fold will return
NotFound HTTP message back to the client.
In the same way we can do
We look for the
Item with the given id. If it exists then we delete it. Then we return accordingly using
TodoService code looks like this.
We need to expose all these
Endpoints from our application. Finch uses Shapeless to compose
Endpoints and taking a closer look to the
TodoService we can see that this composition is happening in the
Let’s look how our application can be rewritten to serve the
.api is the combination of every single
This composition is done using Shapeless and it is basically saying that the incoming request must match one of the endpoints.
Finch is an HTTP library that presents an easy way to define endpoints and to compose them into a more complex API. Finch allows us to write purely functional code for the web that is able to server request at hight rates.