DEV Community

Lucas Barret
Lucas Barret

Posted on • Updated on

How to write a Basic Web Server with Scala 3

Hi everyone so not so long ago I have decided to learn Scala.
And of Scala 3 is out so I have decided to write it with some Scala 3 idioms. Since I do not want to make this project overcomplicated, I have not used a build tool like sbt, maven or gradle.
In fact Scala Community is making a lot of work to make Scala more beginner friendly. And this come from example with the Scala-cli tool, which I am going to use.

From what I have seen, Scala 3 is retro compatible with Scala 2.
But from my perspective there is no Scala 3 Basic Web Server Article.
So here I will give my path to writing a Scala basic web server with AkkaHttp and scala 3.

I will try to introduce some Scala 3 concepts. And explain them at best. But if you want a deep dive in Scala 3 The Scala 3 book is the way. The docs of Scala 3 is very informative and really cool.

So let's begin :

Scala And Akka

So maybe you are wondering, ok so what it is the cool cli which will generate every file I need. Or Okay so I am sure I am going to force to use some built tool like maven.
So there is some tools like that. Maven, Gradle work with Scala. But There is a really cool tool that enable you to prototype really fast. It is called scala-cli. Yes just that ahah !

So all you need is create a scala file !

So the server code is not really complicated here it is :

//> using scala "3.1.3"
//> using dep "com.typesafe.akka::akka-actor-typed:2.7.0"
//> using dep "com.typesafe.akka::akka-http:10.5.0"
//> using dep "com.typesafe.akka::akka-http-spray-json:10.5.0"
//> using dep "com.typesafe.akka::akka-stream:2.7.0"

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import scala.concurrent.ExecutionContext.Implicits.global


object QuickStartApp {

    @main def startServer() = {
      given system: ActorSystem = ActorSystem("MoviesServer")
      val route = path("movies" / "heartbeat") {
        get {
          complete("OK")
        }
      }
      val server = Http().newServerAt("localhost", 8080).bind(route)
      server.map { _ => 
        println("Server online at http://localhost:8080/")
      }  recover { case ex => 
        println(s"Server could not start: ${ex.getMessage}")
      }
    }
}
Enter fullscreen mode Exit fullscreen mode

So now I think it is time to explain some part of this code.
First let's dig in :

//> using ...
Enter fullscreen mode Exit fullscreen mode

This is the using directives this is not Scala code. The
using is use for the scala-cli tool to know the global context, the dependencies the jvm and many more things for your scala app.

Then we have the :

@main def startServer() = ...
Enter fullscreen mode Exit fullscreen mode

Scala use the main function as an entrypoint for your programs. Since Scala 3 @main enables define any method as main. It has replace an old version which was using an App Trait (Trait are basically interfaces).

And after that here you go you define your server, your routes and so on. It is pretty straightforward.

I will just precise the :

given system: ActorSystem = ActorSystem("MoviesServer")
Enter fullscreen mode Exit fullscreen mode

The given will define the system as a contextual parameter.
It will could be use in any other methods, without passing it around in a method call.

But what is the ActorSystem, you would ask ?
I think I am going to make a full article about that later.
Keep in touch ! :D

Conclusion

I love FP x OOP it feels great. Hope you learn something about it. If you see wrong things or better way to do that in a really idiomatic way for example. Do not hesitate to
And I love the work of the Scala community to make it simpler for newcomers.
I think I am going to continue my dive in this beautiful language and make some others articles.

Top comments (1)

Collapse
 
dejvid profile image
dejvid

Link to the book doesnt work :(

Thx for this quick example. Very useful.