Akka HTTP Pokemon

In this tutorial, we are going to explore how to use Akka HTTP to create a very simple Scala based REST services for our Pokemon game.

What is Akka HTTP-01

Prerequisite

This tutorial assumes some working knowledge of Scala and Akka.

What is Akka HTTP

Akka-Http is an Akka based HTTP library for building RESTful services in scala. It’s is not framework, it’s part of the Akka libraries. We are going to use it to expose our Actors to the web via HTTP.

AkkaHTTPPokemon-01

Let’s get started. First, we need to add the Akka HTTP libraries to our project. Here is the sbt build file.

resolvers += Resolver.jcenterRepo

 

libraryDependencies ++= {
val akkaV = “2.4.7”
val sprayJsonV = “1.3.2”
Seq(
“com.typesafe.akka” %% “akka-http-core” % akkaV,
“com.typesafe.akka” %% “akka-http-experimental” % akkaV,
“com.typesafe.akka” %% “akka-http-spray-json-experimental” % akkaV,
“io.spray” %% “spray-json” % sprayJsonV
)
}

Looking at the dependencies we added, we have

  • akka-http-core-experimental: As our http server and requires akka-stream which we included also in our class path.

 Code structure

Normally we divide our RESTful API to two following pieces

  • PokemonService – Defines the route for the rest service.
  • PokemonServer – Defines and creates the Http server to run our

This approach of separating concerns of the API allows us to decouple the system in which the rest service actually runs.

Pokemon REST service

trait PokemonService {
implicit val system: ActorSystem
implicit val materializer: ActorMaterializer

val list = new ConcurrentLinkedDeque[Pokemon]()

import ServiceJsonProtocol.pokemonProtocol

val route =
path(“pokemons”) {
post {
entity(as[Pokemon]) {
pokemon =>
complete {
list.add(pokemon)
s”Caught pokemon ${pokemon.name}!!!”
}
}
} ~
get {
complete {
list.asScala
}
}
}
}

The above code defines a trait called PokemonService and observe, in PokemonService, we have:

  • system – ActorSystem on which this service runs
  • materializer – Flow materializer which we’ll explain shortly

Both values are implicits it allows us to use Scala dependency injection to inject these externally once we instantiate our service.

ActorFlowMaterilizer

Akka HTTP uses akka reactive streams for stream processing. So in a reactive system, we have to specify the flow materializer that handles how the requests and response flow get processed.

In akka-http, actors will be used for handling request and response flows. That’s why in our Pokemon example we have define an  ActorMaterializer

implicit val materializer:ActorMaterializer

The route

Route specifies the URI endpoints REST server exposing. It is combination of multiple paths. A simple path will have the following three parts:

  • Directive/URI
  • HTTP Method
  • Response

In our Pokemon service, we’ve defined our route as follows:
val route =
path(“pokemons”) {
post {
entity(as[Pokemon]) {
pokemon =>
complete {
list.add(pokemon)
s”Caught pokemon ${pokemon.name}!!!”
}
}
} ~
get {
complete {
list.asScala
}
}
}
}

Once the REST service is ready, we can now define a REST server, which we’ll serve this service.

class PokemonServer(implicit val system: ActorSystem, implicit val materializer: ActorMaterializer) extends PokemonService {

 

def startServer(address: String, port: Int) = {

Http().bindAndHandle(route, address, port)

}

}

object PokemonServer {

def main(args: Array[String]) {

implicit val actorSystem = ActorSystem(“pokemon-server”)

implicit val materializer = ActorMaterializer()

val server = new PokemonServer()

server.startServer(“localhost”, 8080)

}

}

Basically, we created an Http server running on port 8080 which will handle all connections to the PokemonService

Consuming Pokemon Service

Now, the exciting part, let’s see how we consume our shining Pokemon service – hopefully, we get  one million downloads too.

To add our newly caught Pokemon, do a POST to the /pokemons endpoint

curl -H “Content-Type: application/json” -X POST -d ‘{“name”: “monster”}’ http://localhost:8080/pokemons

Caught pokemon monster!!!

And to see all our Pokemons, do a GET the /pokemons endpoint

curl -H “Content-Type: application/json” http://localhost:8080/pokemons

[{
“name”: “monster”
}, {
“name”: “Zooo”
}]

Conclusion

Note, we’ve barely scratched the surface but this should give you some ideas of what Akka HTTP is and the next tutorial will go deeper to show you more powerful features of Akka HTTP.

You can download the complete sample code

References

https://www.javacodegeeks.com/2015/02/building-a-rest-service-in-scala-with-akka-http-akka-streams-and-reactive-mongo.html

http://blog.madhukaraphatak.com/akka-http-testing/

 

Show Buttons
Hide Buttons
Contact Us