Getting started with micro-services using Scala, Akka HTTP, and Squbs

Full source code for this article is available here.

Squbs are software containers that provide an infrastructure for combining many micro-services together. One advantage of using squbs for infrastructure is they allow loosely coupled micro-services to communicate with one another using actor messaging.

Here I will show how to create a simple micro-service that takes a simple message as an input and logs it to the console.

Hello World Example

Step 1: Create a new SBT project

I use IntelliJ IDEA to accomplish this. In this project, I will be using Scala 2.11.8 and Squbs 0.9.0.

Step 2: Add project dependencies to build.sbt file

val squbsV = "0.9.0"
libraryDependencies ++= Seq(
"org.squbs" %% "squbs-unicomplex" % squbsV,
"org.squbs" %% "squbs-actormonitor" % squbsV,
"org.squbs" %% "squbs-httpclient" % squbsV,
"org.squbs" %% "squbs-admin" % squbsV,
"com.typesafe.akka" %% "akka-http-spray-json" % "10.0.6"
)

Step 3: Set the location of your main class

To do this, add the following line to the bottom of your build.sbt file.

mainClass in (Compile, run) := Some("org.squbs.unicomplex.Bootstrap")

Step 4: Setup your project’s resources folder

Create a config file under the file path: src/main/resources/squbs-meta.conf.

The squbs-meta.conf file is used for telling Squbs about the actors and services inside of this micro-service. In our example, our squbs-meta.conf looks like this:

# name used to reference this micro-service from other micro-services
cube-name = com.demo.hello_world

cube-version = "1.0-SNAPSHOT"

squbs-actors = [
{
# path to the class
class-name = com.demo.HelloWorld
# arbitrary name used for calling this actor throughout your system
name = hello_world_actor
}
]

squbs-services = [
{
# path to the class
class-name = com.demo.HelloWorldService
# arbitrary name that will be used in the URL path when you call this service
web-context = "hello_world"
}
]

Step 5: Define a case class to use for sending messages to the HelloWorld actor

The JSON body of an HTTP POST message will be parsed into this case class and sent to the HelloWorld actor.

case class PrintMessage(text: String)

Step 6: Create the HelloWorld actor

This is a very basic actor that handles the PrintMessage case class by logging it’s contents to the info log. It looks like this:

class HelloWorld extends Actor with ActorLogging {

override def receive: Receive = {
case PrintMessage(text) =>
printMessage(text)
}

private def printMessage(text: String) = log.info(text)

}

Note that nothing in this actor is unique to squbs. It is a standard Akka Actor.

Step 7: Create the HelloWorld Service

Here we define a service that extends org.squbs.unicomplex.RouteDefinition. Inside of this service, we define the route that we wish to call to send the message to the HelloWorld actor. To talk to the HelloWorld actor, we will use its actor path.

Actor paths within Squbs are defined in the form “user/name_of_squb/name_of_actor” where the names of the squb and actor are the ones you defined in your squbs-meta.conf file. In this example, the path to the HelloWorld actor is: “user/hello_world/hello_world_actor” .

We use the actor path to call the HelloWorld actor from the route as follows:

val route = {
post {
path("print_message") {
entity(as[PrintMessage]) { message =>
context.system.actorSelection("user/hello_world/hello_world_actor") ! message
complete(StatusCodes.OK)
}
}
}
}

Step 8: Run the project and test

Go to to root directory of your project on the command line and run sbt run to test your project. You can then use an HTTP test tool like Paw or Postman to hit the endpoint http://localhost:8080/hello_world/print_message with the JSON body:

{
"text": "Hello World!"
}

This should be enough to get you started with building micro-services! If you have questions, ask in the comments below or @lewisjkl on Twitter.

For more information on squbs, check out their github repo here.