How to implement a REST Web Service using Akka?

22,437

Solution 1

The important thing to realize about Akka is that it's not an all-or-nothing environment. You can, to a large degree, mix and match different libraries to compose the system that makes sense for you. For instance, I have written apps that use Dropwizard fronting a backend which uses Akka, without issue. I have also done the same with Clothesline (implemented in Clojure, but with a Scala wrapper). And later this week, I hope to experiment with using Unfiltered's websocket implementation to sit in front of Akka and a RabbitMQ pipe for feeding near real-time data to the client browsers -- I specifically mention this example because the Unfiltered websocket impl sits on top of Netty rather than a servlet container).

Update: Since having written this answer a few years back, I've begun using Spray exclusively for RESTful development with Akka. While pretty much any JVM REST library can be used, Spray fits very naturally into Akka's actor-based model and the library has clearly reached a level of maturity where it can easily be the default choice. The upcoming integration of Spray into Akka as the new akka-http module is a clear indication of this.

Solution 2

If you want the CODE to do it, then here it is. It took me a bit to really figure out what's going on, because there are a TON of examples, and it's not clear what they are all doing or how to put it all together. Turns out it was more simple than I thought:

package com.nthalk.akkatest

import akka.actor.Actor.actorOf
import akka.actor.Actor
import akka.camel.Consumer
import akka.camel.Message
import akka.camel.CamelServiceManager

class MyActor extends Actor with Consumer {
  def endpointUri = "jetty:http://localhost:8877/"
  def receive = {
    case msg: Message => { self.reply("State Rest Service: Achieved") }
    case _ => { self.reply("Really, no message?") }
  }
}

object App extends scala.App {
  actorOf[MyActor].start
  CamelServiceManager.startCamelService
}

And my build.sbt looks like:

organization := "com.nthalk"

name := "akkatest"

version := "0.1.0"

resolvers += 
  "Typesafe Repository" at "http://repo.typesafe.com/typesafe/releases/"

libraryDependencies ++= Seq(
  "org.apache.camel" % "camel-jetty" % "2.9.0",
  "se.scalablesolutions.akka" % "akka-camel" % "1.3.1"
  )

Hope this helps!

Solution 3

For completeness, it seems useful to have a Scalatra example (since the question asked about Scalatra). Here's some example code from the Scalatra Akka Guide:

package com.example.app

import akka.actor.{ActorRef, Actor, Props, ActorSystem}
import akka.dispatch.ExecutionContext
import akka.util.Timeout
import org.scalatra.FutureSupport
import org.scalatra.{Accepted, ScalatraServlet}

class MyActorApp(system:ActorSystem, myActor:ActorRef) extends ScalatraServlet with     FutureSupport {

  protected implicit def executor: ExecutionContext = system.dispatcher

  import _root_.akka.pattern.ask
  implicit val timeout = Timeout(10)

  get("/async") {
    new AsyncResult { def is = myActor ? "Do stuff and give me an answer" }
  }

  get("/fire-forget") {
    myActor ! "Hey, you know what?"
    Accepted()
  }
}

class MyActor extends Actor {
  def receive = {
    case "Do stuff and give me an answer" => sender ! "The answer is 42"
    case "Hey, you know what?" => println("Yeah I know... oh boy do I know")
  }

}

Solution 4

HTTP servlets and the many containers out there is a tried and trusted technology. Akka offers you the choice of its own embedded servlet container, or you can use it with your own.

You can, of course, roll your own web server with Netty, and there's an interesting write-up about this on the web.

Solution 5

using akka-http (people also call it spray-2.0) which is based on akka-streams.

Share:
22,437
Kamesh Rao Yeduvakula
Author by

Kamesh Rao Yeduvakula

Hands on design, implementation and debugging experience with Big Data systems using Hadoop/Java, Kafka, HBase, Cassandra, Hive and AWS Tech like S3, DynamoDB, SQS, SNS, SWF. Quick learning skills and ability to apply the right tool for the problem. Hands on knowledge of Java/J2EE/Spring for complex, scalable and distributed backend development using caching systems of Redis/Memcache for sub-100ms response times. Using RoR for Rapid Prototyping of MVP. Mobile App development using iOS. Extensive and comprehensive experience of operating, firefighting, debugging, fixing high scale and distributed systems handling 90+ billion requests on a daily basis deployed on a fleet of 2000+ machines. Knowledge of tools and techniques to monitor such systems effectively and efficiently. Varied and extensive domain experience and expertise in Advertising (RTB platforms, bidding engines, identity and cookie matching, targeting, reporting), eCommerce/mCommerce (content ingestion, storefronts for mobile, payment system integration, reporting, analytics), Geo Spatial Apps (geo tracking platforms, mobile/web app development), Video/Multimedia and Social Media Applications. Early career 6+ years startup experience involving multi roles of Product Management and Marketing beyond the technical (Architect/CTO) roles delivering results in a timely fashion to help pitch for the ever-pivoting product and platform. Entry-level understanding and knowledge of Machine Learning algorithms and associated tools and techniques. Hands on experience with gRPC, FlatBuffers, Protobuf, RocksDB, RAFT consensus based system design and implementation.

Updated on June 22, 2020

Comments

  • Kamesh Rao Yeduvakula
    Kamesh Rao Yeduvakula about 4 years

    I intend to implement a pure Akka powered REST based Web API. I am not sure about using spray. I would consider using Scalatra if it is any good. Basically I am interested in using the concurrency benefits of Scala Actor model. I don't want the Servlet container to be an hindrance in that process.

    What can be other options?

    Update 1: Which is better frontend for implementing REST based on Akka backend? - Spray, Scalatra or Dropwizard or any other?