Introduction to Akka Http

Reading Time: 2 minutes

Akka Http

The Akka HTTP modules implement a full server- and client-side HTTP stack on top of akka-actor and akka-stream.

You can read more in-depth about akka-http from here.

Here, we are going to use Intellij for the project setup and Scala as a programming language.

The steps are as follows:-

1. Importing library dependencies

"com.typesafe.akka" %% "akka-http"   % "10.1.8" 
"com.typesafe.akka" %% "akka-stream" % "2.5.25"

2. Creating User case class

We are going to create User user for CRUD operation

case class User(name : String, email : String)

3. Creating User DAO (Data Access Object)

Here, the Future as a return type defines as async operation

import scala.concurrent.Future

trait UserDAO
{
    def insertUser(user : User) : Future[User]
    
    def getUser(email : String) : Future[User]
}

4. Implementing User DAO

We are going to implement UserDAO using mutable a map for this blog but this implementation must be done using a database like MySql, DynamoDB, etc.

class UserDAOImplementation extends UserDAO
{
    val userMap : mutable.Map[String, User] = 
                          scala.collection.mutable.Map[String, User]()
    
    override def insertUser(user : User) = Future {
        userMap += (user.email -> user)
        userMap(user.email)
    }
    
    override def getUser(email : String) = Future {
         userMap(email)
    }
}

5. Writing akka-http Routes

class UserRoutes(userDAO : UserDAO) extends Directives
{
    implicit val userJsonFormat = jsonFormat2(User)
    
    def routes = concat(
        post
        {
            path("add-user")
            {
                entity(as[User])
                {
                    user =>
                    {
                        onComplete(userDAO.insertUser(user))
                        {
                            case Success(user) => complete(user)
                            case Failure(exception) =>
                             exception.printStackTrace()                               
                             complete(StatusCodes.InternalServerError)
                        }
                    }
                }
            }
        },
        get
        {
            path("get-user")
            {
                parameter("email")
                {
                    email =>
                    {
                        onComplete(userDAO.getUser(email))
                        {
                            case Success(user) => complete(user)
                            case Failure(_) => 
                             complete(StatusCodes.BadRequest)
                        }
                    }
                }
            }
        }
    )
}

6. Writing Main method and starting server


object Main extends App
{
    val userDAO = new UserDAOImplementation
    
    val routes : Route = new UserRoutes(userDAO).routes
    
    implicit val system : ActorSystem = ActorSystem("actor-system")
    
    implicit val materializer: ActorMaterializer = ActorMaterializer()
    
    val bindingFuture = Http().bindAndHandle(routes,"localhost",8091)
    
    bindingFuture.onComplete{
        case Success(done) => 
            println("Server started")
            println("Press Enter to stop")
            scala.io.StdIn.readLine()
            system.terminate()
        case Failure(exception) => 
            exception.printStackTrace()
            system.terminate()
    }
}

Now, this will start our akka-http server and we can now hit the endpoints using postman and see the working of our routes.

POST request output
GET request output

Hope This Helps. For any queries, feel free to comment.

Stay Tuned for more.

Leave a Reply