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.
- 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
- Twitter Server:It provides elegant integration with twitter flags for parameterizing external server configuration, an HTTP admin interface, tracing functionality, lifecycle management, and stats.
- Twitter-Util: A bunch of idiomatic, small, general purpose tools for Scala.
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 :
- 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 - 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
Reblogged this on Anmol Sarna and commented:
Finatra : Building Rest APIs Made Simple