Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Shopping Basket App

Creating a shopping basket system using Akka actors in Scala involves several key steps, including defining messages for adding items to the basket and checking out, as well as creating actor behaviors to handle these actions. Below is a simplified example demonstrating these concepts.

Step 1: Define Messages and Data Models

First, define the messages that will be used to interact with the actors, and any data models needed for the shopping basket.

sealed trait BasketCommand
final case class AddItem(item: Item) extends BasketCommand
final case object Checkout extends BasketCommand
final case class Item(name: String, price: BigDecimal)
final case class Receipt(items: List[Item], total: BigDecimal)

Step 2: Define the BasketActor

The BasketActor will maintain a list of items as the state and handle AddItem and Checkout messages.

import akka.actor.typed.Behavior
import akka.actor.typed.scaladsl.Behaviors

object BasketActor {
  def apply(): Behavior[BasketCommand] = basket(List.empty)

  private def basket(items: List[Item]): Behavior[BasketCommand] =
    Behaviors.receive { (context, message) =>
      message match {
        case AddItem(item) =>
          context.log.info(s"Item added to basket: ${item.name}")
          basket(items :+ item)

        case Checkout =>
          val total = items.map(_.price).sum
          context.log.info(s"Checking out with total: $total")
          // In a real application, you might want to send the receipt to another actor or persist it.
          Behaviors.stopped
      }
    }
}

Step 3: Set Up the Actor System and Test

Now, you can set up an ActorSystem, create a BasketActor, and send messages to test the functionality.

import akka.actor.typed.ActorSystem

object ShoppingApp extends App {
  val system: ActorSystem[BasketCommand] = ActorSystem(BasketActor(), "shoppingSystem")

  system ! AddItem(Item("Apple", BigDecimal("0.60")))
  system ! AddItem(Item("Banana", BigDecimal("0.40")))
  system ! Checkout

  // Shutdown the actor system after a short delay to see the output.
  Thread.sleep(1000) // Not ideal for real applications, just for demonstration
  system.terminate()
}

Considerations for a Real Application

  • Persistence: For a production system, you would want to persist the shopping basket's state using Akka Persistence to handle failures and system restarts without data loss.
  • Security: Ensure that each shopping basket is associated with a specific user session or account.
  • Concurrency Handling: Be mindful of concurrent modifications if your system allows for simultaneous updates to the basket from the same user.
  • Scalability: Consider how your actors will be distributed in a clustered environment to handle scaling requirements.
  • Integration: Think about how this system will integrate with other components, like inventory management, payment processing, and user authentication.