by Miguel Lopez

How you can build a Hello World API with Scala and Akka HTTP

Yes, it’s still a thing.

Photo by Blake Connally on Unsplash

Akka is a popular actor-based toolkit for building concurrent and distributed applications in the JVM. These applications mostly use Scala or Java.

It has several modules that help to build such applications, and Akka HTTP is one of them.

Akka HTTP has both client-side and server-side utilities. We will focus on the server in this tutorial.

You should be familiar with Scala, and you should have SBT and IntelliJ setup and installed. If that’s not the case, check the official docs.

Without further ado, let’s build a hello world API using Scala and Akka HTTP!

Project setup

Feel free to clone the repo, make sure you are using the branch 2.1-review-project.

If not, we’ll be using sbt 1.1.6 and Scala 2.12.6 . Check your and build.sbt files to make sure the versions there match these.

Let’s start by adding the required dependencies. Because Akka HTTP depends on actors and streams, we’ll need to add those libraries as well.

Add the following snippet at the end of your build.sbt file:

libraryDependencies ++= Seq(  "com.typesafe.akka" %% "akka-actor" % "2.5.13",  "com.typesafe.akka" %% "akka-stream" % "2.5.13",  "com.typesafe.akka" %% "akka-http" % "10.1.3",)

If you’re prompted to enable auto-import, do it. Otherwise you can open a terminal and cd into the root directory of your project. Then run sbt update to get the dependencies.

Auto-import will make sure to update your project every time certain files are updated, including the build.sbt file.

Instantiate dependencies

Let’s create a Scala object under “src/main/scala” named Server. We will start by instantiating the dependencies required to create a server with Akka HTTP.

First, the object will extend the App trait:

object Server extends App {}

This will allow our Server object to be runnable.

We will need a host and a port to bind the server, so let’s add them now:

val host = ""val port = 9000

Because Akka HTTP uses Akka actors and streams underneath, we will need to supply their dependencies as well:

implicit val system: ActorSystem = ActorSystem("helloworld")implicit val executor: ExecutionContext = system.dispatcherimplicit val materializer: ActorMaterializer = ActorMaterializer()

Even though you don’t need to know what they do to start developing Akka HTTP applications, it’s always good to be aware of what they’re for.

An ActorSystem is used to manage actors. It is used for creating and looking them up. Actors in the same system typically share the same config.

The ExecutionContext is in charge of executing Future s. It knows where and how it should execute them, for example in a thread pool.

And finally, an ActorMaterializer is in charge of running streams.

With that done, we can create our hello route!

Create the route

To create our route, we will use Akka HTTP’s routing DSL. It is based on “layers” of what’s called a directive. For an overview, feel free to browse their official docs.

Add the route below the dependencies:

def route = path("hello") {  get {    complete("Hello, World!")  }}

We have a first layer, where we try to match the incoming request’s path as “/hello”. If it doesn’t match it will be rejected.

If it matches it will try to match inner “directives”. In our case we are matching GET requests. We complete the request/response cycle with a “Hello, World” message.

Start the server

With our route created, all we need to do is start the server:

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

We are binding our route to the given host and port using the Akka HTTP Http object.

To run our Server object, you can right-click it and hit Run ‘Server’.

Give it a couple of seconds to compile, then go to a browser. Navigate to http://localhost:9000/hello and you should see our “Hello, World!” message.


Cool, isn’t it?


Before wrapping up this tutorial we’ll add basic logging to our server.

You might have noticed that there was no feedback when we ran our Server object. We have no clue whether it succeeded or failed.

We can only assume it worked because the application didn’t crash.

Let’s add some logging to it.

If you look into the bindAndHandle function from the Http object, it returns a future of ServerBinding . We can hook some logs into the future’s onComplete function.

Let’s do that:

val bindingFuture = Http().bindAndHandle(route, host, port)bindingFuture.onComplete {  case Success(serverBinding) => println(s"listening to ${serverBinding.localAddress}")  case Failure(error) => println(s"error: ${error.getMessage}")}

Run the Server again, and this time you should see:

listening to /0:0:0:0:0:0:0:0:9000

Wrapping up

While using Scala and Akka HTTP is not the fastest way to develop APIs, it allows you to integrate other Akka modules, such as actors, streams, clusters, and more, making it easier to develop resilient and scalable systems.

Having said that, it’s good to keep in mind that developing an application using Scala and/or Akka doesn’t necessarily mean that it will be resilient and scalable. You’ll still need to perform work to accomplish that, but it’s easier than with other technologies.

If you liked Akka HTTP, we’ve got a free course that’ll quickstart your way into developing APIs with it. You’ll build an API for a Todo application, explained step by step. Check it out! ??

Akka HTTP Quickstart
Learn how to create web applications and APIs with Akka HTTP in this free course!