I previously wrote a post where I tried to figure out what Finagle HTTP services is all about, more precisely I tried to implement a small REST Api. When writing the post I discovered that most people are using Airframe or Fitch instead of vanilla Finagle when doing such a task.
This post is a continuation of the previous post where I will look at Airframe and try to use it to implement the same REST Api once again.
This is not an expert post about Finagle and it’s echo system, it’s my attempt to get an understanding what Finagle is all about.
airframe-http is a library for creating REST HTTP web servers at ease. airframe-http-finagle is an extension of airframe-http to use Finagle as a backend HTTP server.
This sounds good, in my previous post where I used vanilla Finagle HTTP to create a REST Api for a Todo app I had to write a lot of boilerplate code to handle stuff like error handling and transforming JSON to Scala objects, it would be really nice if this was handled by the framework.
The Todo app should support the following API:
It should be possible to send in a request body for the POST and PUT methods:
The id is optional.
Lets start by implementing an endpoint that makes it possible to create a Todo:
Airframe takes care of transforming our json payload to a Todo
. Since I wanted the title and completed fields to be mandatory I had to mark them with a @required
annotation, otherwise Airframe gives me default values which is not what I want (read about id here).
The state of the app is inside an Actor, so the endpoint is pretty trivial, just ask for the Actor to create the Todo and then return the result (all in a non blocking fashion of course).
The rest of the endpoint are implemented in the same way:
And this is how you start the application:
The first part is all about setting up the Actor system.
We then create a router
where we say that the TodoApi
will resolve the requests. We also configure the Finagle server with the router and the port to use. Last but not least we do some dependency injection which we will cover in the next section.
Consider the following rows in the service setup:
Here we bind concrete instances of the SystemContext, ExecutionContextExecutor and the ActorSystem to the types. These are later injected when the TodoApi
class is instantiated.
Here we get references to the context, an Executor and the ActorSystem.
Most of the error handling is taken care of by Airframe (for example validation of the payload), but I added a Filter to take care if the cases when a clients tries to do things with a non existing Todo.
You can find the implementation at github together with the rest of the code.
Airframe takes care of a lot of boilerplate code which is very nice. If I compare with my previous post where I used vanilla Finagle I could skip a lot of code, and the code that was left was clearer to read.
Also, if you come from the Spring Boot world you feel right at home with the Dependency injection and annotation thingies. This might be a good way to introduce Scala on a Java/Spring Boot centric company.
All code is available at github.
Happy coding!