Finatra : Building Rest APIs Made Simple

Finatra is an open-source project by Twitter that can be used to build REST APIs in Scala programming language. Finatra is a framework for easily building API services on top of  Twitter-server, Finagle, and Twitter-util.

  1. Finagle: It provides the building blocks for most of the code we write on the JVM. It has long-served as our extensible, protocol-agnostic, highly-scalable RPC framework
  2. Twitter Server:It provides elegant integration with twitter flags for parameterizing external server configuration, an HTTP admin interface, tracing functionality, lifecycle management, and stats.
  3. Twitter-Util: A bunch of idiomatic, small, general purpose tools for Scala. 

1---tqJ-9f9eLNZU2kh0zmFg


Finatra allows you to easily define a server and (in the case of an HTTP service) controllers — a service-like abstraction which define and handle endpoints of the server. You can also compose filters either per controller, per route in a controller, or across controllers.

 

Building A Simple Hello Application

 

In This Blog , We Will Begin With a Simple Application Which will return a Simple Message Using Finatra.

Let’s Begin.

Step 1: Create a New SBT project

 

Using Intellij Idea , Create a new Sbt Project in order to Start Building The Application from Scratch.

 

Step 2: Adding required dependencies to build.sbt


Add the Following to Your build.sbt :

lazy val versions = new {
  val finatra = "2.1.2"
  val logback = "1.1.3"
}

resolvers ++= Seq(
  Resolver.sonatypeRepo("releases"),
  "Twitter Maven" at "https://maven.twttr.com"
)

libraryDependencies += "com.twitter.finatra" % "finatra-http_2.11" % versions.finatra
libraryDependencies += "com.twitter.finatra" % "finatra-slf4j_2.11" % versions.finatra
libraryDependencies += "ch.qos.logback" % "logback-classic" % versions.logback

Please Note : Only libraryDependencies += com.twitter.finatra % finatra-http_2.11 % versions.finatra is required. Other libraryDependencies are optional but are prefered to keep track of the logs.

Note : There may be a version error while running the code . This will display a error like
//Error

Exception in thread "main" java.lang.NoSuchMethodError: com.twitter.util.Closable.$init$(Lcom/twitter/util/Closable;)V

at FinatraServer.(Finatra.scala:_)
 at FinatraApp$.(Finatra.scala:_)
at FinatraApp$.(Finatra.scala) 
at FinatraApp.main(Finatra.scala)

In order to Correct that try changing the Scala Version to 2.11.7

Step 3: Importing the Finatra HttpServer

 

Add the Following import to your scala class :

import com.twitter.finatra.http.HttpServer

Step 4: Using the Finatra HttpServer By Extending it

 

class FinatraServer extends HttpServer

object FinatraMain extends FinatraServer

Note : The reason for having a separate object is to allow server to be instantiated multiple times in tests without worrying about static state persisting across test runs in the same JVM. (Documentation)

Step 5: Working On the Main Code Using HelloContainer

 

import com.twitter.finagle.http.Request
import com.twitter.finatra.http.routing.HttpRouter
import com.twitter.finatra.http.{Controller, HttpServer}

object FinatraMain extends FinatraServer

class FinatraServer extends HttpServer {
  override protected def configureHttp(router: HttpRouter): Unit = {
    router.add(new HelloController)
  }
}

class HelloController extends Controller {

  get("/hello") { request: Request =>
    "Hello From Anmol. Let's Learn Finatra"
}

In the code shown above, we created HelloController which extends finatra Controller abstract class. HelloController is defined with one endpoint – /hello.

When an HTTP GET request is made to /hello then the associated callback function will be called. The callback function has callback: RequestType => ResponseType signature. It accepts a com.twitter.finagle.http.Request and returns back a response of any type that can be converted to com.twitter.finagle.http.Response .
The callback function in this case just returns a string.

Step 6:  Making the Http GET Request

 

To make The Http Request , We can basically Use 2 methods :

  1. Request From Terminal :
    curl -i http://localhost:8888/hello
    Response :
    HTTP/1.1 200 OK
    Content-Length: 37
    Hello From Anmol. Let’s Learn Finatra 
  2. Request Through Browser : 
    http://localhost:8888/hello
    Response On Browser Window:
    Hello From Anmol. Let’s Learn Finatra 

Similarly you can Add multiple End Points in the application to make Multiple Requests .

 

Testing Of the Hello Application

Step 1 :

In order to test the Application Controller we need to add Certain Things to built.sbt such that your build.sbt looks something like this :

lazy val versions = new {
  val finatra = "2.1.2"
    val logback = "1.1.3"
  val guice = "4.0"

}

resolvers ++= Seq(
  Resolver.sonatypeRepo("releases"),
  "Twitter Maven" at "https://maven.twttr.com"
)

libraryDependencies += "com.twitter.finatra" % "finatra-http_2.11" % versions.finatra
libraryDependencies += "com.twitter.finatra" % "finatra-slf4j_2.11" % versions.finatra
libraryDependencies += "ch.qos.logback" % "logback-classic" % versions.logback
libraryDependencies += "com.twitter.finatra" % "finatra-http_2.11" % versions.finatra % "test"
libraryDependencies += "com.twitter.inject" % "inject-server_2.11" % versions.finatra % "test"
libraryDependencies += "com.twitter.inject" % "inject-app_2.11" % versions.finatra % "test"
libraryDependencies += "com.twitter.inject" % "inject-core_2.11" % versions.finatra % "test"
libraryDependencies += "com.twitter.inject" %% "inject-modules" % versions.finatra % "test"
libraryDependencies += "com.google.inject.extensions" % "guice-testlib" % versions.guice % "test"
libraryDependencies +=  "com.twitter.finatra" % "finatra-jackson_2.11" % versions.finatra % "test"

libraryDependencies += "com.twitter.finatra" % "finatra-http_2.11" % versions.finatra % "test" classifier "tests"
libraryDependencies += "com.twitter.inject" % "inject-server_2.11" % versions.finatra % "test" classifier "tests"
libraryDependencies += "com.twitter.inject" % "inject-app_2.11" % versions.finatra % "test" classifier "tests"
libraryDependencies += "com.twitter.inject" % "inject-core_2.11" % versions.finatra % "test" classifier "tests"
libraryDependencies += "com.twitter.inject" % "inject-modules_2.11" % versions.finatra % "test" classifier "tests"
libraryDependencies += "com.google.inject.extensions" % "guice-testlib" % versions.guice % "test" classifier "tests"
libraryDependencies +=  "com.twitter.finatra" % "finatra-jackson_2.11" % versions.finatra % "test"  classifier "tests"

libraryDependencies += "org.scalatest" % "scalatest_2.11" % "2.2.4" % "test"
libraryDependencies += "org.specs2" %% "specs2" % "2.3.12" % "test"

 

Step 2 :

Add the Following Code to Your Test class in order to test your controller :

import com.twitter.finagle.http.Status
import com.twitter.finatra.http.test.EmbeddedHttpServer
import com.twitter.inject.server.FeatureTest

class HelloControllerSpec extends FeatureTest {
  override val server: EmbeddedHttpServer = new EmbeddedHttpServer(
    twitterServer = new FinatraServer)

  "Saying Hello" in {
    server.httpGet(
      path = "/hello",
      andExpect = Status.Ok,
      withBody = "Hello From Anmol. Let's Learn Finatra"
    )
  }
}

 

Step 3 :

Finally sbt test from the terminal to ensure that the application passes the test.

 

 

For Further Reference, Check out the Official Link : https://github.com/twitter/finatra

For the Demo Hello Application, Check out Our Github Link  : https://github.com/anmol2709/Finatra_Application_For_Beginners.git

 


KNOLDUS-advt-sticker

Written by 

Anmol Sarna is a software consultant having more than 1.5 years of experience. He likes to explore new technologies and trends in the IT world. His hobbies include playing football, watching Hollywood movies and he also loves to travel and explore new places. Anmol is familiar with programming languages such as Java, Scala, C, C++, HTML and he is currently working on reactive technologies like Scala, Cassandra, Lagom, Akka, Spark and Kafka.

1 thought on “Finatra : Building Rest APIs Made Simple

Leave a Reply

%d bloggers like this: